hiểu giá trị mặc định của IFS


10

Trong phiên bản bash GNU 4.2.8 của tôi, IFS có giá trị mặc định là không gian, tab và nguồn cấp dữ liệu theo mặc định:

usr@T42 ~ $ echo -n "$IFS" | hexdump -C
00000000  20 09 0a                                          | ..|
00000003
usr@T42 ~ $ 

Có một lý do cho IFS mặc định như vậy? Ngoài ra, tiện ích nào sử dụng IFS bên cạnh bash tích hợp read?

Câu trả lời:


13

Biến IFS được sử dụng mỗi khi shell thực hiện một tác vụ gọi là tách từ . Các trường hợp phổ biến nhất được sử dụng là sau khi mở rộng tham số (ví dụ $var) hoặc thay thế lệnh (ví dụ $(some-command)hoặc backticks không dùng nữa) trong một lệnh. Ở đây nếu bản mở rộng chứa bất kỳ IFSký tự nào , thì nó sẽ chia thành các 'từ' khác nhau trước khi lệnh được xử lý. Thực tế, điều này có nghĩa là các ký tự này phân chia văn bản được thay thế thành các đối số khác nhau (bao gồm tên của lệnh nếu biến được chỉ định trước).

Do đó, lý do cho giá trị mặc định IFSlà khoảng trắng, tab và dòng mới là vì đây là các ký tự khoảng trắng thường được dự kiến ​​sẽ phân tách một từ.

Một cách để ngăn chặn việc chia tách từ xảy ra là sử dụng dấu ngoặc kép xung quanh phần mở rộng ( "$var") - thực tế bạn đã thực hiện điều này trong câu hỏi của mình. Nếu bạn không làm điều này thì sẽ không có đầu ra echovì nó sẽ không có đối số, chỉ có các ký tự tách các đối số.

Cũng lưu ý rằng hai vị trí phân tách từ không xảy ra sau khi mở rộng tham số bằng phép gán biến (ví dụ var=$othervarvar=$(somecommand)là ok) và trong [[ ]]cấu trúc ( [[ $var = $othervar ]]là ok, nhưng [ $var = $othervar ]nên được trích dẫn).

Cuối cùng, như một người khôn ngoan đã từng chỉ ra cho tôi, một quan niệm sai lầm phổ biến là việc ngăn chặn việc chia tách từ là lý do duy nhất để trích dẫn một biến. Không, trích dẫn cũng ngăn chặn việc mở rộng tên đường dẫn hoặc mở rộng toàn cầu vì nó được biết đến nhiều hơn. Nếu một biến chứa các ký tự toàn cục như thế *thì chúng có thể được mở rộng thành tên tệp khi biến được sử dụng không được trích dẫn trong lệnh. Ví dụ: xem xét:

var=*
echo $var

Điều này sẽ hiển thị tên của các tập tin trong thư mục hiện tại.

Như Stephane chỉ ra bên dưới , thứ tự các ký tự bên trong IFSrất có ý nghĩa khi mở rộng "$*". Từ bashtrang người đàn ông:

"$*" is equivalent to "$1c$2c...", where c is the first character of the value of
the IFS variable.  If IFS is unset, the parameters are separated by spaces.  If
IFS is null, the parameters are joined without intervening separators.

Để biết thêm ví dụ về phân tách từ, vui lòng xem câu trả lời này - https://unix.stackexchange.com/a/118444/48083


1
Ký tự đầu tiên $IFScũng được sử dụng trong "$*"đó là lý do tại sao thứ tự quan trọng.
Stéphane Chazelas

2
Cũng lưu ý rằng zshbao gồm ký tự NUL mặc định $IFS(các shell khác không hỗ trợ giữ ký tự NUL trong các biến của chúng).
Stéphane Chazelas
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.