У деяких оболонках (у тому числі bash
):
IFS=: command eval 'p=($PATH)'
(з bash
, ви можете опустити command
емуляцію, якщо не, в sh / POSIX). Але майте на увазі, що при використанні змін без котирувань вам також зазвичай потрібно set -f
, і немає локальної області для цього в більшості оболонок.
З zsh ви можете:
(){ local IFS=:; p=($=PATH); }
$=PATH
полягає в примусовому розбитті слів, яке не робиться за замовчуванням у zsh
(глобалізація при зміні розширення не робиться, тому вам не знадобиться, set -f
якщо тільки в емуляції sh).
(){...}
(або 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[]
. Це насправді не присвоєння змінної, але більше змінних середовищ змінних виконуваної команди. У оболонці Борна чи Корна, з 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, у тире, pdksh та bash, але не в ksh 93u. Незвично бачити, що ksh є незвичайним, невідповідним.