В некоторых оболочках (в том числе bash
):
IFS=: command eval 'p=($PATH)'
(с помощью bash
, вы можете опустить, command
если не в эмуляции sh / POSIX). Но имейте в виду, что при использовании переменных без кавычек вам, как правило, это необходимо set -f
, и в большинстве оболочек для этого нет локальной области действия.
С Zsh вы можете сделать:
(){ local IFS=:; p=($=PATH); }
$=PATH
заключается в принудительном разделении слов, которое по умолчанию не выполняется zsh
(глобализация при раскрытии переменных также не выполняется, поэтому вам не нужно ничего, set -f
кроме эмуляции).
(){...}
(или function {...}
) называются анонимными функциями и обычно используются для установки локальной области видимости. с другими оболочками, которые поддерживают локальную область видимости в функциях, вы можете сделать что-то похожее с:
e() { eval "$@"; }
e 'local IFS=:; p=($PATH)'
Чтобы реализовать локальную область видимости для переменных и параметров в оболочках POSIX, вы также можете использовать функции, представленные по адресу https://github.com/stephane-chazelas/misc-scripts/blob/master/locvar.sh . Тогда вы можете использовать его как:
. /path/to/locvar.sh
var=3,2,2
call eval 'locvar IFS; locopt -f; IFS=,; set -- $var; a=$1 b=$2 c=$3'
(кстати, разделение $PATH
таким способом выше недопустимо , за исключением случаев, zsh
когда, как и в других оболочках, IFS является разделителем полей, а не разделителем полей).
IFS=$'\n' a=($str)
Это просто два задания, одно за другим просто так a=1 b=2
.
Примечание объяснения на var=value cmd
:
В:
var=value cmd arg
Оболочка выполняется /path/to/cmd
в новом процессе и проходит cmd
и arg
в argv[]
и var=value
в envp[]
. На самом деле это не присвоение переменных, а передача переменных окружения в исполняемую команду. В оболочке Bourne или Korn set -k
вы можете даже написать это cmd var=value arg
.
Теперь это не относится к встроенным функциям или функциям, которые не выполняются . В Bourne оболочки, в var=value some-builtin
, в var
конце концов быть установлен после этого, так же , как с в var=value
одиночку. Это означает, например, что поведение var=value echo foo
(которое бесполезно) варьируется в зависимости от того echo
, встроен он или нет.
POSIX и / или ksh
изменил это так, что поведение Борна происходит только для категории встроенных функций, называемых специальными встроенными функциями . eval
это особый встроенный, read
нет. Для не специальных встроенных функций, var=value builtin
устанавливает var
только для выполнения встроенной функции, которая заставляет его вести себя так же, как при выполнении внешней команды.
command
Команда может быть использована для удаления специального атрибута этих специальных встроенных команд . Однако POSIX упустил из виду то, что для встроенных eval
и .
встроенных команд это означало бы, что оболочкам придется реализовывать стек переменных (даже если он не указывает команды ограничения local
или typeset
области действия), потому что вы можете сделать:
a=0; a=1 command eval 'a=2 command eval echo \$a; echo $a'; echo $a
Или даже:
a=1 command eval myfunction
с myfunction
является функцией использования или установки $a
и потенциально вызова command eval
.
Это было действительно упущением, потому что ksh
(на котором спецификация в основном основана) не реализовало его (а AT & T ksh
и zsh
до сих пор не реализовало ), но в настоящее время, за исключением этих двух, большинство оболочек реализуют его. Поведение варьируется среди оболочек, хотя в таких вещах, как:
a=0; a=1 command eval a=2; echo "$a"
хотя. Использование local
поддерживаемых оболочек - более надежный способ реализации локальной области видимости.
IFS=: command eval …
устанавливаетIFS
только для продолжительностиeval
, как предписано POSIX, в dash, pdksh и bash, но не в ksh 93u. Необычно видеть, что ksh нечетный, не соответствует требованиям.