Por lo general, $0en una secuencia de comandos se establece el nombre de la secuencia de comandos, o lo que se invocó como (incluida la ruta). Sin embargo, si lo uso bashcon la -copción, $0se establece en el primero de los argumentos pasados después de la cadena de comando:
bash -c 'echo $0 ' foo bar 
# foo 
En efecto, parece que los parámetros posicionales se han cambiado, pero incluidos $0. Sin embargo, shiften la cadena de comando no afecta $0(como es normal):
bash -c 'echo $0; shift; echo $0 ' foo bar
# foo
# foo
¿Por qué este comportamiento aparentemente extraño para las cadenas de comandos? Tenga en cuenta que estoy buscando la razón, la justificación, detrás de la implementación de un comportamiento tan extraño.
Se podría especular que una cadena de comandos de este tipo no necesitaría el $0parámetro como se define generalmente, por lo que para economía también se usa para argumentos normales. Sin embargo, en ese caso el comportamiento de shiftes extraño. Otra posibilidad es que $0se usa para definir el comportamiento de los programas (a la bashllamada as sho vimllamada as vi), pero eso no puede ser, ya que $0aquí solo se ve en la cadena de comandos y no por los programas llamados dentro de ella. No puedo pensar en ningún otro uso $0, así que no puedo explicarlo.

-para el$0argumento como un modismo, como ensh -c 'foo $1 $2' - a b. De esta manera se ve bastante normal (una vez que descubriste lo que eso-significa, eso es)echo 'echo the other side of this pipe globs "$@"' | sh -s -- *embargo, también puede , desafortunadamente,$0generalmente no ser un parámetro configurable con la-sopción de tream ... Sin embargo, se puede usar de muchas de las mismas manerasxargs. Y otros además.--, entonces eso podría haber tenido la interpretación habitual de 'desde aquí comienza los argumentos', visto en algunos otros programas. Por otra parte, eso podría confundir a aquellos que no están familiarizados con-cpensar que--realmente tienen esa interpretación.Respuestas:
Eso le da la oportunidad de configurar / elegir
$0cuando usa un script en línea. De$0lo contrario, simplemente seríabash.Entonces puedes hacer, por ejemplo:
No todos los proyectiles solían hacer eso. El caparazón Bourne lo hizo. El shell Korn (y Almquist) eligió tener el primer parámetro en su
$1lugar. POSIX con el tiempo se fue por la forma de Bourne, de modokshyashderivados volvía al nivel más tarde (más sobre esto en http://www.in-ulm.de/~mascheck/various/find/#shell ). Eso significó que durante mucho tiemposh(que dependiendo del sistema se basó en el shell Bourne, Almquist o Korn), no sabías si el primer argumento entró$0o$1, por lo que para la portabilidad, tenías que hacer cosas como:O:
Afortunadamente, POSIX ha especificado el nuevo comportamiento donde entra el primer argumento
$0, por lo que ahora podemos hacer de forma portátil:fuente
bash -c 'echo txt files are "$@"' meaningful-arg0-for-error *.txten Ubuntu 14.04, fiestaversion 4.3.11(1)-release, y tengo:txt files are *.txt. Ootxtarchivos en el directorio actual). Ver tambiénbash -c 'echo "${1?}"' foosh -c 'shift "$2"; echo txt files are "$@"' tentative-arg0 3 2 *.txtes fantásticamente inventivo!SHELL -c 'shift $1; command' 2 1 arg1 arg2 ...jaja ...POSIX define este comportamiento :
En cuanto a por qué querrías ese comportamiento: esto suaviza la brecha entre un script y una
-ccadena. Puede convertir directamente entre los dos sin ningún cambio de comportamiento. Otras áreas confían en que estas sean idénticas.También está en línea con la forma en que funcionan los argumentos del programa en general: en última instancia, esto se reduce a llamar a una de las
execfunciones, en la que también está el primer argumento proporcionado$0, e igualmente comúnmente ese argumento es el mismo que el ejecutable que está ejecutando. A veces, sin embargo, desea un valor especial allí, y simplemente no habría otra forma de obtenerlo. Dado que el argumento existe, tiene que asignarse a algo, y el usuario debe poder establecer qué es eso.Esta coherencia (y probable accidente histórico) conduce a la situación que encuentra.
fuente
argv[0].$0solo se establece en elargv[0]pasado aexecve()cuando es comoshobash. Para los scripts,$0se establece en la ruta dada como argumento 1, 2 ... al intérprete (y para los scripts ejecutados directamente, eso proviene del primer argumento de ruta a execve ()).