Obvykle $0
ve skriptu je nastaveno na název skriptu nebo na cokoliv, jako byl vyvolán (včetně cesty). Pokud však použiji bash
pomocí -c
možnost, $0
je nastaveno na první z argumentů předávaných po řetězci příkazu:
bash -c 'echo $0' foo bar
# foo
Ve skutečnosti se zdá, že poziční parametry byly posunuty, ale včetně $0
. Nicméně shift
v příkazovém řetězci nemá vliv na $0
(jako obvykle):
bash -c 'echo $0; shift; echo $0' foo bar
# foo
# foo
Proč toto zdánlivě podivné chování příkazových řetězců?
Všimněte si, že hledám důvod, zdůvodnění, které stojí za implementací takového podivného chování.
Dalo by se spekulovat, že takový příkazový řetězec nebude potřebovat $0
parametr, jak je obvykle definován, takže pro hospodárnost se používá i pro normální argumenty. V takovém případě však chování shift
je lichý. Další možností je, že $0
se používá k definování chování programů (a la bash
nazývá se sh
nebo vim
nazývá se vi
), ale to nemůže být, protože $0
zde je vidět pouze v příkazovém řetězci a ne programy, které jsou v něm volány. Nenapadá mě žádné jiné využití pro $0
, takže nevím, jak to vysvětlit.
Přijatá odpověď:
To vám dává příležitost nastavit/zvolit $0
při použití vloženého skriptu. Jinak $0
by bylo jen bash
.
Pak můžete udělat například:
$ 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
Ne všechny skořápky to dělaly. Bourne shell ano. Shell Korn (a Almquist) se rozhodl, že první parametr bude $1
namísto. POSIX nakonec zvolil Bourneův způsob, takže ksh
a ash
deriváty se k tomu později vrátily (více o tom na http://www.in-ulm.de/~mascheck/various/find/#shell). To znamenalo, že po dlouhou dobu pro sh
(který byl v závislosti na systému založen na Bourneově, Almquistově nebo Kornově shellu), nevěděli jste, zda se první argument dostal do $0
nebo $1
, takže kvůli přenositelnosti jste museli udělat věci jako:
sh -c 'echo foo in "$1"' foo foo
Nebo:
sh -c 'shift "$2"; echo txt files are "[email protected]"' tentative-arg0 3 2 *.txt
Naštěstí POSIX specifikoval nové chování, kde je první argument v $0
, takže nyní můžeme přenosně provést:
sh -c 'echo txt files are "[email protected]"' meaningful-arg0-for-error *.txt