Что такое $ * и $ # в Linux?

82

Что означают следующие переменные среды в Linux?

  1. Что такое $ * (знак доллара, сопровождаемый звездочкой)?
  2. Что такое $ # (знак доллара рядом с хэш-знаком / знаком числа / октоторпа / знака фунта)?
raghavayc
источник

Ответы:

115

От сюда :

$#    Stores the number of command-line arguments that 
      were passed to the shell program.
$?    Stores the exit value of the last command that was 
      executed.
$0    Stores the first word of the entered command (the 
      name of the shell program).
$*    Stores all the arguments that were entered on the
      command line ($1 $2 ...).
"$@"  Stores all the arguments that were entered
      on the command line, individually quoted ("$1" "$2" ...).

Таким образом, в основном, $#это ряд аргументов, приведенных при выполнении вашего скрипта. $*это строка, содержащая все аргументы. Например, $1это первый аргумент и так далее. Это полезно, если вы хотите получить доступ к определенному аргументу в вашем скрипте.

Как прокомментировал Брайан, вот простой пример. Если вы выполните следующую команду:

./command -yes -no /home/username
  • $# = 3
  • $* знак равно -yes -no /home/username
  • $@ = массив: {"-yes", "-no", "/home/username"}
  • $0= ./command, $1= -yesи т. д.

Они являются частью стандарта POSIX и должны поддерживаться всеми совместимыми оболочками. Для справки ниже приведены стандартные определения POSIX для каждого специального параметра. Обратите внимание , что есть три дополнительные переменные: $-, $$и $!.

$@:

Расширяется до позиционных параметров, начиная с единицы. Когда расширение происходит в двойных кавычках, и когда выполняется разделение поля (см. Разделение поля ), каждый позиционный параметр должен раскрываться как отдельное поле, при условии, что расширение первого параметра все еще должно быть объединено с начальной частью исходное слово (при условии, что расширенный параметр был встроен в слово), а расширение последнего параметра все равно должно быть объединено с последней частью исходного слова. Если позиционных параметров нет, расширение «@» будет генерировать нулевые поля, даже если «@» заключено в двойные кавычки.

$*:

Расширяется до позиционных параметров, начиная с единицы. Когда раскрытие происходит в строке, заключенной в двойные кавычки (см. Двойные кавычки ), оно должно раскрываться до одного поля, в котором значение каждого параметра отделяется первым символом переменной IFS или если IFS не установлен. Если для IFS задана нулевая строка, это не эквивалентно ее отмене; его первый символ не существует, поэтому значения параметров объединяются.

$#:

Расширяется до десятичного числа позиционных параметров. Имя команды (параметр 0) не должно учитываться в числе, указанном в «#», поскольку это специальный параметр, а не позиционный параметр.

$?:

Расширяется до десятичного состояния выхода самого последнего конвейера (см. Конвейеры ).

$-:

(Дефис.) Расширяется до флагов текущих параметров (однобуквенные имена параметров, объединенные в строку), как указано при вызове, с помощью специальной встроенной команды set или неявно с помощью оболочки.

$$:

Расширяется до десятичного идентификатора процесса вызванной оболочки. В подоболочке (см. Среда выполнения оболочки ) значение $ должно быть таким же, как и у текущей оболочки.

$!:

Расширяется до десятичного идентификатора процесса самой последней фоновой команды (см. Списки ), выполняемой из текущей оболочки. (Например, фоновые команды, выполняемые из подоболочек, не влияют на значение «$!» В текущей среде оболочки.) Для конвейера идентификатор процесса равен идентификатору последней команды в конвейере.

$0:

(Ноль.) Расширяется до имени оболочки или сценария оболочки. Смотрите sh для подробного описания того, как это имя получено.

Олли
источник
1
Эти специальные параметры верны для всех оболочек, полученных из Борна (например, sh, bash, dash, ash, ksh, zsh).
Деннис Уильямсон
Исправление: $*и $#1) переменные оболочки, а не переменные окружения; 2) стандартизированный (часть спецификации POSIX)
grawity
3
Также обратите внимание, что "$@"много раз записывается как ${1+"$@"}(по соображениям переносимости), см. Stackoverflow.com/questions/743454/… для объяснения.
Хловдал
Поскольку «Имя команды (параметр 0) не должно учитываться ...», в приведенном выше примере должно быть $ # = 2, начиная с 0.
Йозеф Климук
0

$# представляет количество аргументов:

[root@baymax ~]# set -- a
[root@baymax ~]# echo $#
1

[root@baymax ~]# set -- a b c
[root@baymax ~]# echo $#
3
Vikk_King
источник
2
Добро пожаловать в Супер пользователя. Сайт представляет собой базу знаний, поэтому каждый ответ должен дать решение вопроса, который еще не был представлен. Это касается только половины вопроса, и информация уже хорошо освещена в предыдущем ответе.
fixer1234