Por ejemplo, el siguiente comando no funciona:
if [[-e xyz]]; then echo File exists;fi
ksh da el siguiente error
[[-e: command not found
¿Es porque "[[-" es ambiguo?
command-line
syntax
ksh
AcBap
fuente
fuente

[[es una palabra clave - presumiblemente árbol de análisis sintáctico de la cáscara requiere que las palabras clave deben ser delineadas por espacios en blancoRespuestas:
La explicación más simple sería, ya que en el manual se presenta como
[[ expression ]]lo que tiene que haber espacio entre[[yexpressiony cierre]]. Pero, por supuesto, podemos intentar verlo más en profundidad. Los shells tienen una gramática algo compleja y dependen en gran medida del concepto de "división de palabras". En particular, el manual ksh (1) establece:Entonces, como se indica en el manual, la secuencia de caracteres
[[-ese considera una palabra shell.kshbuscaría dicho comando en la lista de incorporados y operadores especiales (comoforowhile), luego buscaría un comando externo, y voilà, ninguno encontrado, por lo tanto, hay un mensaje de error sobre el comando no encontrado.En este caso
[[tampoco son metacaracteres especiales. Si lo fueran, la-eparte en[[-ese consideraría una palabra shell, no un argumento en[[sí mismo. Sin embargo,[[se describe como comando compuesto, y el manual dice lo siguiente:Por lo tanto, para
[[ser reconocido como un comando compuesto, debe ser la primera palabra de un comando o lista de comandos, lo que por definición previa de una "palabra" implica que debe estar separado por espacios, tabulaciones o líneas nuevas de otros palabras / argumentos.Has preguntado en los comentarios : "¿Por qué el analizador no puede detenerse tan pronto como encuentra el patrón" [["y lo trata como el inicio de un comando condicional?" La respuesta corta probablemente se deba a que 1) influye en la
[sintaxis, ya que originalmente era un comando externo, y para el cumplimiento estándar POSIX existe como comando externo incluso hoy, y 2) porque el analizador de shell está construido de esta manera. El analizador de shell puede reconocer otros caracteres especiales no delimitados por espacios:echo $((2+2))y(echo foobar)funciona perfectamente bien. Tal vez en el futuro cuando sekshreanude el desarrollo o parezca haber una bifurcación o clon (comomkshopdksh) alguien implementará una sintaxis sin espacio[[-e.Ver también:
[[se denomina "palabra reservada" (consulte la sección 2.9 del lenguaje de comandos de Shell ). Por definición POSIX, la palabra reservada tiene que estar delimitada por espacios. Por el contrario,(es un operador, y los estados estándar en la sección 2.9 "las representaciones incluyen el espacio entre los tokens en algunos lugares donde<blank>s no sería necesario (cuando uno de los tokens es un operador)". Vea la discusión relacionada: Gramática de shell POSIX: ¿por qué Brace Group necesita el primer espacio pero Subshell no?fuente
chares una palabra clave, pero aún no puede escribircharsomeletter = 'A';y esperar que el analizador se detenga después de verchar.i--<=++j, y el compilador no tiene problemas para analizar eso comoi -- <= ++ j._). Ksh tiene(como operador y(echo hello)analiza como( echo hello ). Haif,{,[[, y otras palabras clave , yifx,{xy[[xson cada uno un token - como la formacharsomeletteres una ficha C. En contraste, un sin comillas(xen ksh son dos tokens, como cómoi--son dos tokens en C. Lo que conceptualmente significa ser un operador difiere entre los shells de estilo Bourne (como ksh) y C. Pero Peter A. Schneider señaló un similitud léxica real .Es importante tener en cuenta que
[es un comando, y la palabra clave de shell[[en bash y ksh se basa en[.[[se usa de manera similar a[. A veces incluso se puede sustituir[]con[[]]sin cambio en el comportamiento. Con[, como cualquier comando, un espacio es obligatorio entre el comando y sus argumentos. Lo mismo se aplica a[[.Solíamos tener solo
/usr/bin/[. Ahora la mayoría de los shells se han[incorporado para la eficiencia, pero la sintaxis es la misma. En los depósitos que proporcionan[[, funciona como una alternativa más versátil para[.Aquí está la descripción de
[en bash:Entonces
[es equivalente atest(aparte de esperar un]argumento al final).help testdará aún más detalles al respecto. Puedes comparar esto conhelp [[.También hay una página de manual para el comando externo
[(man \[).En el caso de
[tampoco[[es un comando, allí. La palabra completa[[-ees.if [[-econvierte en una prueba de verdadero / falso. Entonces , ¿ existe un comando[[-e?Si. O no.
[[-ees lo que es: nada que el shell entienda, por lo que supone que es su propio comando. ;-)fuente
[[-ees un nombre de comando potencialmente válido (si se ve raro).El espacio es un deliminador y es obligatorio. Como puedes ver en
shellcheck:(Tanto ksh como bash admiten
[[y no funcionan sin el espacio. Shellcheck proporciona exactamente esa salida con scripts ksh y bash similares que contienen esa línea con errores).Por qué se necesitan delimitadores tiene que ver con tokens y léxicos .
fuente
kshshell en la pregunta. Bash toma prestado[[operadorkshy de esta tela de juicio su comportamiento es idéntico, pero me gustaría tener cuidado de supuestos ya que hay algunas diferencias significativas entrekshybashel comportamiento y el funcionamiento interno. Eso es solo porque shellcheck funciona en script bash, puede que no sea necesariamente una herramienta apropiada para scripts ksh. Solo algo a tener en cuenta al acercarse a diferentes proyectiles[[reglas integradas. De ninguna manera deduje quekshera un caparazón en el queshellcheckpodría encontrar errores. Espero que otros lo aprecienkshybashsean dos intérpretes diferentes. Gracias por mencionar eso. También vale la pena señalar que[[es un bash incorporado, mientras que[es un comando externo.[también es una función integrada en bash :) manpages.ubuntu.com/manpages/bionic/man7/bash-builtins.7.html Pero no está lejos,[otestdebe ser un comando externo. En los días de Bourne Shell original[era, de hecho, un comando externo, y todavía existe hoy en día/usr/bin/[porque POSIX requiere que sea un comando externo pubs.opengroup.org/onlinepubs/009695399/utilities/test.html POSIX requiere muy pocos ser incorporado pubs.opengroup.org/onlinepubs/009695399/idx/sbi.html Builtin[es para la eficienciaksh; usar un hashbang o-s ksh. Btw, ksh y bash se han[["incorporado", pero es una palabra clave , a diferencia de[, que es un shell incorporado . (ksh :;whence -v [ [[bashtype [ [[:) Los comandos internos y externos son sintácticamente similares. Una forma diferente[[de esto[es que[[suprime algunas expansiones en sus argumentos, lo que no podría ser como un componente integrado, al igual{que no podría agruparse si fuera un elemento integrado. Esta puede ser la razón por la cual{x(o[[x) ser una ficha se siente extraño. Creo que es correcto decir que las palabras clave y las palabras clave son léxicas pero no sintácticamente similares. @SergiyKolodyazhnyy[[puede ser un comando externo! Es decir, puede ser un programa y no una sintaxis compatible con su shell directamente. Sería posible soportar una sintaxis sin espacio,kshpero fallaría en sistemas con sistema externo,[[por lo que por razones de compatibilidad es mejor mantener el espacio requerido.BusyBox se proporciona
[[como un comando externo , por ejemplo.fuente
Dado que
[[-epuede participar en la expansión de shell (se puede usar comopara enumerar todos los archivos que comienzan con una letra entre
[eeinclusive), sería un completo desastre si[y si]los caracteres especiales no participaran en la división normal de palabras gobernada por espacios en blanco.fuente