Dostęp do args linii poleceń bash $@ vs $*
W wielu tak pytaniach i tutorialach bash widzę, że mogę uzyskać dostęp do args linii poleceń w skryptach bash na dwa sposoby:
$ ~ >cat testargs.sh
#!/bin/bash
echo "you passed me" $*
echo "you passed me" $@
Co daje:
$ ~> bash testargs.sh arg1 arg2
you passed me arg1 arg2
you passed me arg1 arg2
Jaka jest różnica między $*
a $@
?
Kiedy należy korzystać z pierwszego i kiedy należy korzystać z drugiego?
4 answers
Różnica pojawia się, gdy podane są parametry specjalne. Pozwól mi zilustrować różnice:
$ set -- "arg 1" "arg 2" "arg 3"
$ for word in $*; do echo "$word"; done
arg
1
arg
2
arg
3
$ for word in $@; do echo "$word"; done
arg
1
arg
2
arg
3
$ for word in "$*"; do echo "$word"; done
arg 1 arg 2 arg 3
$ for word in "$@"; do echo "$word"; done
arg 1
arg 2
arg 3
Kolejny przykład na znaczenie cytowania: zauważ, że są 2 spacje między " arg " a liczbą, ale jeśli nie zacytuję $word:
$ for word in "$@"; do echo $word; done
arg 1
arg 2
arg 3
I w bash, "$@"
jest "domyślną" listą do iteracji:
$ for word; do echo "$word"; done
arg 1
arg 2
arg 3
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-22 11:20:00
A nice handy overview table from the Bash Hackers Wiki :
Gdzie c
w trzecim wierszu znajduje się pierwszy znak $IFS
, wewnętrznego separatora pól; zmiennej środowiskowej.
Jeśli argumenty mają być przechowywane w zmiennej skryptowej i oczekuje się, że argumenty będą zawierać spacje, z całego serca zalecam użycie "$*"
sztuczka z wewnętrznym separatorem pól $IFS
ustawionym na tab .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-06 09:20:19
$*
Rozszerza się do parametrów pozycyjnych, zaczynając od 1. Kiedy rozszerzenie występuje w podwójnych cudzysłowach, rozszerza się do pojedynczego słowa z wartością każdego parametru oddzieloną pierwszym znakiem zmienna specjalna IFS. Oznacza to, że "$ * "jest równoważne" $1C$2C...", gdzie c jest pierwszym znakiem wartości zmiennej IFS. Jeśli IFS nie jest ustawiony, parametry są oddzielone spacjami. If IFS is null, parametry są łączone bez separatory interwencyjne.
$@
Rozszerza się do parametrów pozycyjnych, zaczynając od 1. Kiedy rozszerzenie występuje w podwójnych cudzysłowach, każdy parametr rozszerza się do osobne słowo. Oznacza to, że "$ @ " jest równoważne "$1 ""$2"... Jeśli ekspansja dwucytowa występuje w obrębie słowa, ekspansja pierwszy parametr jest połączony z początkową częścią oryginału word, a rozszerzenie ostatniego parametru jest połączone z ostatnim część oryginalne słowo. Gdy nie ma parametrów pozycyjnych, "$@"i $@ rozwijają się do zera(tzn. są usuwane).
Źródło: Bash man
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-07 08:36:55
$@ jest taki sam jak$*, ale każdy parametr jest cytowanym łańcuchem znaków, to znaczy parametry są przekazywane w Nienaruszonym Stanie, bez interpretacji lub rozbudowy. Oznacza to między innymi, że każdy parametr na liście argumentów jest postrzegany jako osobne słowo.
Oczywiście, "$ @ " powinno być cytowane.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-07 08:32:33