Що означає знак долара, який супроводжується знаком at-sign ( @
) у сценарії оболонки?
Наприклад:
umbrella_corp_options $@
Що означає знак долара, який супроводжується знаком at-sign ( @
) у сценарії оболонки?
Наприклад:
umbrella_corp_options $@
Відповіді:
$@
- це всі параметри, передані сценарію.
Наприклад, якщо ви зателефонували, ./someScript.sh foo bar
то $@
дорівнює foo bar
.
Якщо ти зробиш:
./someScript.sh foo bar
а потім всередині someScript.sh
посилання:
umbrella_corp_options "$@"
це буде передано umbrella_corp_options
кожному окремому параметру, укладеному у подвійні лапки, що дозволяє взяти параметри з порожнім простором у абонента та передати їх далі.
someScript.sh foo bar "boo far"
?
$@
це не обов'язково походить від параметрів, переданих до сценарію ... наприклад; set a b "x y"; printf '(%s)' "$@"
виходи(a)(b)(x y)
$@
$*
$@
майже те саме $*
, що обоє означають "всі аргументи командного рядка". Вони часто використовуються, щоб просто передати всі аргументи іншій програмі (таким чином формуючи обгортку навколо цієї іншої програми).
Різниця між двома синтаксисами виявляється, коли у вас є аргумент із пробілами в ньому (наприклад) та введені $@
подвійні лапки:
wrappedProgram "$@"
# ^^^ this is correct and will hand over all arguments in the way
# we received them, i. e. as several arguments, each of them
# containing all the spaces and other uglinesses they have.
wrappedProgram "$*"
# ^^^ this will hand over exactly one argument, containing all
# original arguments, separated by single spaces.
wrappedProgram $*
# ^^^ this will join all arguments by single spaces as well and
# will then split the string as the shell does on the command
# line, thus it will split an argument containing spaces into
# several arguments.
Приклад: Дзвінок
wrapper "one two three" four five "six seven"
це призведе до:
"$@": wrappedProgram "one two three" four five "six seven"
"$*": wrappedProgram "one two three four five six seven"
^^^^ These spaces are part of the first
argument and are not changed.
$*: wrappedProgram one two three four five six seven
wrappedProgram "$*"
-> separated by single spaces.
але у вашому 2-му прикладі вони не розділені між собою проміжками.
Це аргументи командного рядка, де:
$@
= зберігає всі аргументи у списку string
$*
= зберігає всі аргументи у вигляді однієї строки
$#
= зберігає кількість аргументів
Використання чистого $@
засобу в більшості випадків "завдає шкоди програмісту настільки сильно, як ви можете", оскільки в більшості випадків це призводить до проблем з розділенням слова, з пробілами та іншими символами в аргументах.
У (здогадався) 99% всіх випадків, потрібно вкласти це "
: "$@"
чи можна використати для надійної ітерації аргументів.
for a in "$@"; do something_with "$a"; done
for a in start_token "$@" end_token; do something_with "$a"; done
:-)
@
Розширюється на позиційні параметри, починаючи з одиниці. Коли розширення відбувається в межах подвійних лапок, кожен параметр розширюється на окреме слово. Тобто, "$ @" еквівалентно "$ 1" "$ 2" .... Якщо розширення з подвійним цитуванням відбувається в межах слова, розширення першого параметра з'єднується з початковою частиною початкового слова, а розширення останнього параметра з'єднується з останньою частиною початкового слова. Коли немає позиційних параметрів, "$ @" і $ @ розширюються ні до чого (тобто вони видаляються).
Коротше кажучи, $@
розширюється на позиційні аргументи, передані від абонента до функції або сценарію . Його значення залежить від контексту : всередині функції вона розширюється на аргументи, передані такій функції. Якщо використовується в сценарії (не в межах функції), він розширюється на аргументи, передані такому сценарію.
$ cat my-sh
#! /bin/sh
echo "$@"
$ ./my-sh "Hi!"
Hi!
$ put () ( echo "$@" )
$ put "Hi!"
Hi!
Тепер, ще одна тема, яка має першорядне значення при розумінні того, як $@
поводиться в оболонці, - це розділення слів . Оболонка розбиває лексеми на основі вмісту IFS
змінної. Його значення за замовчуванням \t\n
: тобто пробіл, вкладка та новий рядок.
Розширення "$@"
дає вам незайману копію переданих аргументів. Однак розширюватися $@
не завжди. Більш конкретно, якщо аргументи містять символи з IFS
, вони розділяться.
Більшу частину часу те, що ви хочете використовувати, це "$@"
ні $@
.