2010-07-19 7 views
5

En sh:no puede entender la sustitución de comandos en los crustáceos

~$ `echo ls` 
bin/ Desktop/ 

Pero en peces: (. Tenga en cuenta que el mensaje de error aparece por encima de la línea de comandos)

fish: Illegal command name “(echo ls)” 
~% (echo ls) 

~% echo (echo ls) 
ls 
~% eval (echo ls) 
bin/ Desktop/ 

fish: Illegal command name “(echo ls)” 
exec (echo ls) 
    ^
~% exec (echo ls) 

Parece que la sustitución de comandos solo funciona como parámetros de un comando, no como un comando en sí mismo? ¿Por qué?

Bueno, la ayuda doc sí dice

Si un parámetro contiene un conjunto de paréntesis, el texto encerrado por el paréntesis se interpretará como una lista de comandos.

Pero aún así, ¿por qué?

+0

Desde el mensaje de error aparece por encima de la línea de comandos y parece que luego lo editó antes de volver a enviarlo, es confuso ya que ninguno de los comandos que muestra produce ese error. Tal vez deberías insertar '(echo ls)' después del mensaje de error para mayor claridad. –

+0

Lo siento, extraño el '()'. Editado – weakish

Respuesta

4

Cómo

Esto debido a sustituciones de mando pertenecen a las expansiones de los parámetros y no se permiten como comandos.

Un ejemplo similar:

en sh:

tmpls=ls 
$tmpls 

Pero en el pescado:

% set cmd ls; $cmd 
fish: Variables may not be used as commands. 
... 

Por qué

En resumen, es bueno para la verificabilidad

Este article explica detalles:

Puesto que está permitido el uso de las variables como comandos en conchas regular, es imposible comprobar de forma fiable la sintaxis de una secuencia de comandos. Por ejemplo, este fragmento de código bash/zsh puede o no ser legal, dependiendo de su suerte. ¿Te sientes afortunado?

if true; then if [ $RANDOM -lt 1024 ]; then END=fi; else END=true; fi; $END 

Tanto bash y zsh tratar de determinar si el comando en el búfer se termina cuando el usuario pulsa la tecla de retorno, pero debido a problemas de este tipo, que a veces fallar. Peor aún, este pedazo de código perfectamente legal es rechazada por bash:

FI=fi; foo() { if true; then true; $FI; } 

pescado evita este tipo de problemas, ya que las variables no están permitidos como comandos. Cualquier cosa que pueda hacer con las variables como comandos se puede hacer de una manera mucho más limpia utilizando el comando eval o mediante el uso de funciones.

Por la misma razón, las sustituciones de comandos no están permitidas como comandos.

. (Nota: El ejemplo citado no es justo, ya que 'si' y 'fi' no son órdenes sencillas, pero las palabras reservadas Véanse los comentarios a continuación.)

+0

Para una discusión de este problema con respecto a Bash, vea [BashFAQ/050] (http://mywiki.wooledge.org/BashFAQ/050). –

+1

el artículo que cita en su sección "por qué" es completamente erróneo (al menos en lo que respecta a esta sección). Un comando como 'FI = fi; foo() {si es verdadero; entonces verdadero; $ FI; } 'is * not * valid shell syntax, por lo que está marcado correctamente como un error de sintaxis por todas las shells POSIX. Palabras como 'fi' son palabras reservadas, y se reconocen antes de la expansión de palabras que expande' $ FI' a 'fi'. – Gilles

+0

@Gilles Gracias. He editado mi respuesta. – weakish

0

Tiene que ver con el orden de las expansiones.

De help expand-command-substitution en fish:

Cuando la combinación de múltiples expansiones de parámetros, las expansiones se realizan en el siguiente orden:

* Command substitutions 
* Variable expansions 
* Bracket expansion 
* Pid expansion 
* Wildcard expansion 

expansiones se realizan de derecha a izquierda, anidados las expansiones de los soportes se realizan desde el interior y el exterior.

De man bash:

El orden de las expansiones es: expansión de llaves, de tilde, parámetros, variables y la expansión y dominio aritmética sustitución (hecho en una de izquierda a derecha de la moda), la palabra división y expansión del nombre de ruta.

+0

Todavía estoy confundiendo. Parece que Fish no intenta expandir la sustitución Command, y toma (echo ls) literalmente como un comando. – weakish

Cuestiones relacionadas