#bash #variable-assignment
#bash #переменная-назначение
Вопрос:
Для назначения переменных в bash я обычно делаю следующее:
a=1
b=2
c=3
Если это выполняется в одной строке, это будет похоже:
a=1; b=2; c=3
Недавно я видел некоторые коды, такие как:
a=1 b=2 c=3
Назначение разделено пробелом, и оно работает. Я пытался использовать этот подход в Google, но не могу быстро найти ответ из учебника. Прямо сейчас я просто знаю, что это работает.
Итак, поддерживается ли этот синтаксис всеми оболочками или это стандартный подход?
Комментарии:
1.
by all shell
«вся оболочка» — что именно ? Их много2. или «другой оболочкой (например, csh, ksh ..)» был бы лучшим термином.
3. Это явно поддерживается POSIX. Простой команде может предшествовать одно или несколько назначений, и «оператор присваивания» на самом деле является просто простой командой без фактической команды. См. Правила грамматики оболочки , в частности правило 7.
Ответ №1:
это стандартный подход?
ДА.
Из языка оболочки posix 2.9.1 Простые команды, выделение мое:
«Простая команда» — это последовательность необязательных назначений и перенаправлений переменных в любой последовательности, за которыми необязательно следуют слова и перенаправления, завершаемые управляющим оператором.
[…]
Если имя команды не отображается, присвоение переменных должно повлиять на текущую среду выполнения. […]
Это также видно из грамматики оболочки:
simple_command : cmd_prefix cmd_word cmd_suffix
| cmd_prefix cmd_word
| cmd_prefix
| cmd_name cmd_suffix
| cmd_name
cmd_prefix : io_redirect
| cmd_prefix io_redirect
| ASSIGNMENT_WORD
| cmd_prefix ASSIGNMENT_WORD
Вы можете поместить столько назначений (и перенаправлений), сколько хотите, перед command . Если команды нет, назначения будут влиять на текущую оболочку.
Ответ №2:
Да, это работает. Возможным предостережением является SC2155 в том, что вы должны объявлять и назначать отдельно.
При этом это будет работать, за исключением использования нескольких параметров объявления между параметрами. Также обратите внимание, что параметры объявления будут применяться ко всем переменным (в данном случае -i).
script0:
#!/bin/bash
declare a b c
a=foo
b=bar
c=baz
foo () {
local a=1 b=2 c=3
echo "From within func:"
declare -p a
declare -p b
declare -p c
}
foo
echo "From outside func:"
declare -p a
declare -p b
declare -p c
Output:
$ ./script.sh
From within func:
declare -- a="1"
declare -- b="2"
declare -- c="3"
From outside func:
declare -- a="foo"
declare -- b="bar"
declare -- c="baz"
script1:
#!/usr/bin/env bash
declare -i a -a b c
a=foo
b=(bar)
c=baz
foo () {
local -i a=1 -a b=(2) c=3
echo "From within func:"
declare -p a
declare -p b
declare -p c
}
foo
echo "From outside func:"
declare -p a
declare -p b
declare -p c
Output:
$ ./script.sh
./script.sh: line 3: declare: `-a': not a valid identifier
./script.sh: line 9: local: `-a': not a valid identifier
From within func:
declare -i a="1"
declare -ai b=([0]="2")
declare -i c="3"
From outside func:
declare -i a="0"
declare -ai b=([0]="0")
declare -i c="0"
Ответ №3:
POSIX определяет простую команду как
«Простая команда» — это последовательность необязательных назначений и перенаправлений переменных в любой последовательности, за которыми необязательно следуют слова и перенаправления, завершаемые управляющим оператором.
Обратите внимание, что «оператор» присваивания подпадает под это определение: это просто одно или несколько назначений переменных без дополнительных слов, следующих за ними, чтобы указать фактическую команду.
Далее в том же разделе приводится семантика таких назначений без команд:
Назначение переменных должно выполняться следующим образом:
- Если имя команды не отображается, присвоение переменных должно повлиять на текущую среду выполнения.