Điều cần được giải thích là lệnh xuất hiện để hoạt động, không phải mã thoát của nó
'\n'
là hai ký tự: dấu gạch chéo ngược \và chữ cái n. Những gì bạn nghĩ rằng bạn cần $'\n'
là một nguồn cấp dữ liệu (nhưng điều đó cũng không đúng, xem bên dưới).
Các -d
tùy chọn thực hiện điều này:
-d delim continue until the first character of DELIM is read, rather
than newline
Vì vậy, nếu không có tùy chọn đó, read
sẽ đọc đến một dòng mới, chia dòng thành các từ bằng cách sử dụng các ký tự $IFS
làm dấu phân cách và đặt các từ vào mảng. Nếu bạn đã chỉ định -d $'\n'
, đặt dấu phân cách dòng thành một dòng mới, nó sẽ thực hiện chính xác điều tương tự . Cài đặt -d '\n'
có nghĩa là nó sẽ đọc đến dấu gạch chéo ngược đầu tiên (nhưng, một lần nữa, xem bên dưới), là ký tự đầu tiên trong delim
. Vì không có dấu gạch chéo ngược trong tệp của bạn, nên read
sẽ chấm dứt ở cuối tệp và:
Exit Status:
The return code is zero, unless end-of-file is encountered, read times out,
or an invalid file descriptor is supplied as the argument to -u.
Vì vậy, đó là lý do tại sao mã thoát là 1.
Từ thực tế là bạn tin rằng lệnh đã hoạt động, chúng tôi có thể kết luận rằng không có khoảng trắng trong tệp, do đó read
, sau khi đọc toàn bộ tệp với hy vọng vô ích tìm thấy dấu gạch chéo ngược, sẽ phân tách nó bằng khoảng trắng (giá trị mặc định là $IFS
), bao gồm cả các dòng mới. Vì vậy, mỗi dòng (hoặc mỗi từ, nếu một dòng chứa nhiều hơn một từ) được đưa vào mảng.
Vụ án bí ẩn về dấu gạch chéo ngược
Bây giờ, làm thế nào tôi biết tập tin không chứa bất kỳ dấu gạch chéo ngược nào? Bởi vì bạn đã không cung cấp -r
cờ cho read
:
-r do not allow backslashes to escape any characters
Vì vậy, nếu bạn có bất kỳ dấu gạch chéo ngược nào trong tệp, chúng sẽ bị xóa, trừ khi bạn có hai trong số chúng liên tiếp. Và, tất nhiên, có bằng chứng read
có mã thoát là 1, chứng tỏ rằng nó không tìm thấy dấu gạch chéo ngược, vì vậy cũng không có hai trong số chúng liên tiếp.
Hành trình
Bash sẽ không bị bash nếu không có gotchas ẩn đằng sau mỗi lệnh, và read
cũng không ngoại lệ. Đây là một cặp vợ chồng:
Trừ khi bạn chỉ định -r
, read
sẽ diễn giải các chuỗi thoát dấu gạch chéo ngược. Trừ khi đó thực sự là những gì bạn muốn (đôi khi nó là, nhưng chỉ thỉnh thoảng), bạn nên nhớ chỉ định -r
để tránh các ký tự biến mất trong trường hợp hiếm hoi có dấu gạch chéo ngược trong đầu vào.
Việc read
trả về mã thoát là 1 không có nghĩa là nó thất bại. Nó cũng có thể đã thành công, ngoại trừ việc tìm ra kẻ kết thúc dòng. Vì vậy, hãy cẩn thận với một vòng lặp như thế này: while read -r LINE; do something with LINE; done
bởi vì nó sẽ thất bại do something
với dòng cuối cùng trong trường hợp hiếm hoi là dòng cuối cùng không có dòng mới ở cuối.
read -r LINE
bảo tồn dấu gạch chéo ngược, nhưng nó không giữ khoảng trắng hàng đầu hoặc dấu.