Bạn có thể lưu và gán cho IFS khi cần. Không có gì sai khi làm như vậy. Không có gì lạ khi lưu giá trị của nó để khôi phục sau khi sửa đổi tạm thời, nhanh chóng, như ví dụ gán mảng của bạn.
Như @llua đề cập trong bình luận của anh ấy cho câu hỏi của bạn, chỉ cần bỏ đặt IFS sẽ khôi phục hành vi mặc định, tương đương với việc gán một dòng không gian-tab-newline.
Thật đáng để xem xét làm thế nào có thể có vấn đề hơn khi không đặt / hủy đặt IFS một cách rõ ràng hơn là làm như vậy.
Từ phiên bản POSIX 2013, 2.5.3 Biến Shell :
Việc triển khai có thể bỏ qua giá trị của IFS trong môi trường hoặc không có IFS khỏi môi trường, tại thời điểm shell được gọi, trong trường hợp đó, shell sẽ đặt IFS thành <space> <tab> <newline> khi nó được gọi .
Một vỏ được gọi, tuân thủ POSIX có thể hoặc không kế thừa IFS từ môi trường của nó. Từ đây:
- Một tập lệnh di động không thể kế thừa một cách đáng tin cậy IFS thông qua môi trường.
- Một tập lệnh dự định chỉ sử dụng hành vi phân tách mặc định (hoặc tham gia, trong trường hợp
"$*"
), nhưng có thể chạy dưới lớp vỏ khởi tạo IFS từ môi trường, phải đặt / hủy đặt IFS một cách rõ ràng để tự bảo vệ chống lại sự xâm nhập của môi trường.
NB Điều quan trọng là phải hiểu rằng đối với cuộc thảo luận này, từ "được viện dẫn" có một ý nghĩa đặc biệt. Một shell chỉ được gọi khi nó được gọi rõ ràng bằng cách sử dụng tên của nó (bao gồm cả một #!/path/to/shell
shebang). Một lớp con - chẳng hạn như có thể được tạo bởi $(...)
hoặc cmd1 || cmd2 &
- không phải là lớp vỏ được gọi và IFS của nó (cùng với hầu hết môi trường thực thi của nó) giống hệt với lớp mẹ của nó. Một shell được gọi sẽ đặt giá trị của $
pid của nó, trong khi các lớp con kế thừa nó.
Đây không chỉ đơn thuần là một sự bác bỏ phạm vi; có sự khác biệt thực tế trong lĩnh vực này. Đây là một đoạn script ngắn kiểm tra kịch bản sử dụng một số shell khác nhau. Nó xuất một IFS đã sửa đổi (được đặt thành :
) sang một vỏ được gọi và sau đó in IFS mặc định của nó.
$ cat export-IFS.sh
export IFS=:
for sh in bash ksh93 mksh dash busybox:sh; do
printf '\n%s\n' "$sh"
$sh -c 'printf %s "$IFS"' | hexdump -C
done
IFS thường không được đánh dấu để xuất, nhưng, nếu có, hãy lưu ý cách bash, ksh93 và mksh bỏ qua môi trường của chúng IFS=:
, trong khi dash và busybox tôn vinh nó.
$ sh export-IFS.sh
bash
00000000 20 09 0a | ..|
00000003
ksh93
00000000 20 09 0a | ..|
00000003
mksh
00000000 20 09 0a | ..|
00000003
dash
00000000 3a |:|
00000001
busybox:sh
00000000 3a |:|
00000001
Một số thông tin phiên bản:
bash: GNU bash, version 4.3.11(1)-release
ksh93: sh (AT&T Research) 93u+ 2012-08-01
mksh: KSH_VERSION='@(#)MIRBSD KSH R46 2013/05/02'
dash: 0.5.7
busybox: BusyBox v1.21.1
Mặc dù bash, ksh93 và mksh không khởi tạo IFS từ môi trường, chúng vẫn tái xuất IFS đã sửa đổi của chúng.
Nếu vì bất kỳ lý do gì bạn cần chuyển IFS qua môi trường một cách hợp lý, bạn không thể làm như vậy bằng chính IFS; bạn sẽ cần gán giá trị cho một biến khác và đánh dấu biến đó để xuất. Trẻ em sau đó sẽ cần gán giá trị đó một cách rõ ràng cho IFS của chúng.