Di solito, $0
in uno script è impostato sul nome dello script o su qualsiasi cosa sia stato invocato (incluso il percorso). Tuttavia, se utilizzo bash
con il -c
opzione, $0
è impostato sul primo degli argomenti passati dopo la stringa di comando:
bash -c 'echo $0' foo bar
# foo
In effetti, sembra che i parametri posizionali siano stati spostati, ma includendo $0
. Comunque shift
nella stringa di comando non ha effetto su $0
(come di consueto):
bash -c 'echo $0; shift; echo $0' foo bar
# foo
# foo
Perché questo comportamento apparentemente strano per le stringhe di comando?
Nota che sto cercando il motivo, la logica, dietro l'implementazione di un comportamento così strano.
Si potrebbe ipotizzare che una tale stringa di comando non avrebbe bisogno del $0
parametro come di solito definito, quindi per economia viene utilizzato anche per argomenti normali. Tuttavia, in quel caso il comportamento di shift
è strano. Un'altra possibilità è che $0
è usato per definire il comportamento dei programmi (a la bash
chiamato come sh
o vim
chiamato come vi
), ma non può essere, poiché $0
qui è visto solo nella stringa di comando e non dai programmi chiamati al suo interno. Non riesco a pensare ad altri usi per $0
, quindi non riesco a spiegarlo.
Risposta accettata:
Questo ti dà l'opportunità di impostare/scegliere $0
quando si utilizza uno script inline. Altrimenti, $0
sarebbe solo bash
.
Quindi puoi fare ad esempio:
$ echo foo > foo
$ bash -c 'wc -c < "${1?}"' getlength foo
4
$ rm -f bar
$ bash -c 'wc -c < "${1?}"' getlength bar
getlength: bar: No such file or directory
$ bash -c 'wc -c < "${1?}"' getlength
getlength: 1: parameter not set
Non tutte le shell lo facevano. Il Bourne Shell lo ha fatto. La shell Korn (e Almquist) ha scelto che il primo parametro vada a $1
invece. POSIX alla fine ha optato per il metodo Bourne, quindi ksh
e ash
i derivati sono tornati a quello in seguito (maggiori informazioni su http://www.in-ulm.de/~mascheck/various/find/#shell). Ciò significava questo per molto tempo per sh
(che a seconda del sistema era basato sulla shell Bourne, Almquist o Korn), non sapevi se il primo argomento andava in $0
o $1
, quindi per la portabilità, dovevi fare cose come:
sh -c 'echo foo in "$1"' foo foo
Oppure:
sh -c 'shift "$2"; echo txt files are "[email protected]"' tentative-arg0 3 2 *.txt
Per fortuna, POSIX ha specificato il nuovo comportamento in cui il primo argomento va in $0
, quindi ora possiamo fare in modo portatile:
sh -c 'echo txt files are "[email protected]"' meaningful-arg0-for-error *.txt