В некоторых оболочках (в том числе 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 нечетный, не соответствует требованиям.