9 votos

¿Por qué se requiere un espacio en blanco entre "[[" y "-e xxx" en ksh?

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?

15voto

Serg Puntos 17677

La explicación más sencilla sería, ya que en el manual aparece como [[ expression ]] así que tiene que haber espacio entre [[ y expression y cerrando ]]. Pero, por supuesto, podemos intentar un vistazo más en profundidad. Conchas de tener un poco de gramática compleja y se basan en gran medida en el concepto de "palabra de dividir". En particular, ksh(1) manual estados:

La cáscara comienza a analizar su entrada por la ruptura en sus palabras. Palabras, que son secuencias de caracteres, están delimitados por no cotizados caracteres de espacio en blanco (espacio, tabulador y newline) o meta-caracteres (<, >, |, ;, &, ( y )). Aparte de la delimitación de las palabras, los espacios y las tabulaciones son ignorados, mientras que el de nueva línea generalmente delimitar los comandos.

Así como se indica en el manual, de secuencia de caracteres [[-e es considerado como un intérprete de la palabra. ksh sería para tales comando en la lista de construido-ins y operadores especiales ( como for o while ), a continuación, busque un comando externo - y listo - no se halló ninguno, por lo tanto hay un mensaje de error acerca de comando no encontrado.

En este caso, [[ no son especiales meta-caracteres. Si lo fueran, el -e parte [[-e podría ser considerado como un shell de palabra, no un argumento a [[ sí. Sin embargo, [[ se describe como comando compuesto, y el manual dice lo siguiente:

Compuesto de comandos se crean utilizando las siguientes palabras reservadas - estas palabras sólo se reconocen si son sin comillas y si son utilizados como la primera palabra de un comando (es decir, que no puede ser precedida por un parámetro de asignaciones o redirecciones):

Así, en orden de [[ a ser reconocido como un comando compuesto, tiene que ser una primera palabra de un comando o el comando de la lista, que por definición previa de una "palabra" implica que tiene que ser separados por espacios en blanco,tabuladores o saltos de línea de otras palabras y argumentos.


Has preguntado en los comentarios: "¿por Qué no puede el analizador de parada tan pronto como se encuentra "[[el patrón", y lo trata como el inicio de un comando condicional?" Respuesta corta es, probablemente, porque: 1) la influencia de la [ sintaxis ya que fue originalmente un comando externo, y para el estándar POSIX de cumplimiento existe como comando externo incluso hoy en día, y 2) debido a que la cáscara analizador está construido de modo. Shell parser puede reconocer a otros no-espacio delimitado por caracteres especiales: echo $((2+2)) y (echo foobar) funciona perfectamente. Quizás en el futuro cuando ksh desarrollo reanuda o no parece ser un tenedor o un clon (como mksh o pdksh) alguien va a implementar el espacio de menos de sintaxis en [[-e.

Vea también:

2voto

Ayush Goyal Puntos 141

Lo que es importante señalar es que, [ es un comando, el shell palabra clave [[ en bash y ksh se basa en [.

[[ se utiliza de una manera similar a [. A veces usted puede incluso reemplazar [ ] con [[ ]] con ningún cambio en el comportamiento. Con [, al igual que cualquier comando, un espacio es obligatoria entre el comando y sus argumentos. Lo mismo se aplica a [[.

Teníamos /usr/bin/[. Ahora la mayoría de los shells tienen [ integrada para la eficiencia, pero la sintaxis es la misma. En las conchas que proporcionan [[, funciona como una más versátil alternativa a [.

Aquí está la descripción para [ en bash:

$ help [
[: [ arg... ]
    Evaluate conditional expression.

    This is a synonym for the "test" builtin, but the last argument must
    be a literal `]', to match the opening `['.

Por lo [ es equivalente a test (aparte de la espera de una ] argumento al final). help test le dará aún más de detalle. Usted puede comparar esta a help [[.

También hay una página de manual para el comando externo [ (man \[).

En el caso de

if [[-e
  • Ni [ ni [[ es un comando, no. El pleno de la palabra [[-e es.
  • El if [[-e hace un examen de verdadero/falso. Así que hace un comando [[-e existen?

Es que debido a que "[[-" es ambiguo?

Sí. O no. [[-e es lo que es: nada de lo que el shell de entender por lo que se supone es su propia orden. ;-)

2voto

WinEunuuchs2Unix Puntos 1032

El espacio es un deliminator y es necesario. Como se puede ver en shellcheck:

$ shellcheck gmail-browse-msgs-algorithm.sh

In gmail-browse-msgs-algorithm.sh line 847:
        [[$Today != "${DaysArr[ i + DAY_DELETED_ON_NDX ]}" ]] && continue
          ^-- SC1035: You need a space after the [[ and before the ]].

(Ambos chelines y bash apoyo [[ y no funcionan sin el espacio. Shellcheck da exactamente esa salida con similar chelines y scripts de bash que contiene buggy línea).

Por qué deliminators son necesarios tiene que ver con los tokens y léxicos.

0voto

DarkDust Puntos 111

[[ puede ser un comando externo! Es decir, puede ser un programa y no una sintaxis compatible con su intérprete de comandos directamente. El apoyo a un espacio de menos de sintaxis sería posible para ksh pero que no iba a sistemas externos [[ así que por razones de compatibilidad es mejor mantener el espacio necesario.

BusyBox es brindar [[ como un comando externo, por ejemplo.

EnMiMaquinaFunciona.com

EnMiMaquinaFunciona es una comunidad de administradores de sistemas en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros sysadmin, hacer tus propias preguntas o resolver las de los demás.

Powered by: