Trong một số shell (bao gồm bash):
IFS=: command eval 'p=($PATH)'
(với bash, bạn có thể bỏ qua phần commandmô phỏng sh / POSIX) nếu không. Nhưng hãy cẩn thận khi sử dụng các biến không được trích dẫn, nhìn chung bạn cũng cần set -fvà không có phạm vi cục bộ cho điều đó trong hầu hết các shell.
Với zsh, bạn có thể làm:
(){ local IFS=:; p=($=PATH); }
$=PATHlà để buộc chia tách từ mà không được thực hiện theo mặc định zsh(việc mở rộng khi mở rộng biến cũng không được thực hiện nên bạn không cần set -ftrừ khi trong mô phỏng sh).
(){...}(hoặc function {...}) được gọi là các hàm ẩn danh và thường được sử dụng để đặt phạm vi cục bộ. với các shell khác hỗ trợ phạm vi cục bộ trong các hàm, bạn có thể làm điều gì đó tương tự với:
e() { eval "$@"; }
e 'local IFS=:; p=($PATH)'
Để triển khai phạm vi cục bộ cho các biến và tùy chọn trong shell POSIX, bạn cũng có thể sử dụng các hàm được cung cấp tại https://github.com/stephane-chazelas/misc-scripts/blob/master/locvar.sh . Sau đó, bạn có thể sử dụng nó như:
. /path/to/locvar.sh
var=3,2,2
call eval 'locvar IFS; locopt -f; IFS=,; set -- $var; a=$1 b=$2 c=$3'
(bằng cách này, không hợp lệ để phân chia $PATHtheo cách đó, ngoại trừ zshnhư trong các shell khác, IFS là dấu phân cách trường, không phải là dấu tách trường).
IFS=$'\n' a=($str)
Chỉ là hai bài tập, hết lần này đến lần khác a=1 b=2.
Một lưu ý giải thích về var=value cmd:
Trong:
var=value cmd arg
Shell thực hiện /path/to/cmdtrong một quy trình mới và thông qua cmdvà argtrong argv[]và var=valuetrong envp[]. Đó không thực sự là một phép gán biến, nhưng nhiều biến môi trường hơn cho lệnh được thực thi . Trong vỏ Bourne hoặc Korn, với set -k, bạn thậm chí có thể viết nó cmd var=value arg.
Bây giờ, điều đó không áp dụng cho các nội dung hoặc hàm không được thực thi . Trong shell Bourne var=value some-builtin, varcuối cùng , được thiết lập sau đó, giống như với var=valuemột mình. Điều đó có nghĩa là, ví dụ, hành vi của var=value echo foo(không hữu ích) thay đổi tùy thuộc vào việc có echođược dựng sẵn hay không.
POSIX và / hoặc kshthay đổi rằng trong đó hành vi của Bourne chỉ xảy ra đối với một loại nội dung được gọi là nội dung đặc biệt . evallà một nội dung đặc biệt, readkhông. Đối với nội dung không đặc biệt, chỉ var=value builtinthiết lập varcho việc thực thi nội dung khiến nó hoạt động tương tự như khi một lệnh bên ngoài đang được chạy.
Các commandlệnh có thể được sử dụng để loại bỏ các đặc biệt thuộc tính của những builtins đặc biệt . Điều mà POSIX đã bỏ qua là đối với các nội trang evalvà .nội dung, điều đó có nghĩa là các shell sẽ phải thực hiện một ngăn xếp biến (mặc dù nó không chỉ định các lệnh localhoặc typesetgiới hạn phạm vi), bởi vì bạn có thể làm:
a=0; a=1 command eval 'a=2 command eval echo \$a; echo $a'; echo $a
Hoặc thậm chí:
a=1 command eval myfunction
với myfunctionchức năng sử dụng hoặc cài đặt $avà có khả năng gọi command eval.
Đó thực sự là một sự bỏ qua bởi vì ksh(mà thông số kỹ thuật chủ yếu dựa trên) đã không thực hiện nó (và AT & T kshvà zshvẫn không), nhưng ngày nay, ngoại trừ hai, hầu hết các shell đều thực hiện nó. Hành vi khác nhau giữa các vỏ mặc dù trong những thứ như:
a=0; a=1 command eval a=2; echo "$a"
Tuy nhiên. Sử dụng các localshell hỗ trợ nó là một cách đáng tin cậy hơn để thực hiện phạm vi cục bộ.
IFS=: command eval …đặtIFStrong khoảng thời gianeval, như được ủy quyền bởi POSIX, trong dấu gạch ngang, pdksh và bash, nhưng không phải trong ksh 93u. Thật bất thường khi thấy ksh là người không tuân thủ một cách kỳ quặc.