Tại sao điều này trong khi đọc sách này làm việc trong một thiết bị đầu cuối, nhưng không phải trong một kịch bản shell?


8

Tôi gặp phải vấn đề thú vị này trong khi điền vào thanh WM của mình bằng văn bản thông tin, được áp dụng bằng cách đặt tiêu đề của cửa sổ gốc, tức là xsetroot -name "clever words"

Cuối cùng, in một tài sản hoạt động tốt trong một thiết bị đầu cuối:

fortune -s | while read -r; do xsetroot -name "$REPLY"; done

Tuy nhiên, điều đó cũng thất bại khi chạy từ tập lệnh shell:

#!/bin/sh
cat /tmp/afile | while read; do echo "$REPLY"; done

Sản xuất:

$ sh afilerhead
afilerhead: 2: read: arg Count

Tất nhiên điều này được khắc phục bằng cách gán kết quả tài sản của chúng tôi cho một biến, sau đó sử dụng xsetroot với biến đã nói. Nhưng tôi vẫn muốn hiểu tại sao điều này không hoạt động trong một kịch bản.

Tôi nhận ra mỗi lệnh ở hai bên của đường ống được chạy trong lớp con riêng của nó, nhưng không thấy các biến cục bộ của chúng có thể ảnh hưởng đến vòng lặp đọc như thế nào. Hoặc là các biến ngoài phạm vi ngay cả giữa các vòng lặp lặp?

Tôi đang thiếu gì?

Cập nhật: Các shtôi đã sử dụng được liên kết với dấu gạch ngang, đó là trong quá trình đang được thực hiện POSIX tuân thủ. Sử dụng đáng kính hơn đã bashgiải quyết điều này.


1
hành vi của dash ở đây không biểu hiện bất kỳ sự thiếu tuân thủ POSIX nào. POSIX không yêu cầu rằng bất readkhả xâm phạm mà không có biến: pubs.opengroup.org/onlinepub/9699919799/utilities/read.html
dubiousjim

Câu trả lời:


10

Bạn dường như đang chạy ví dụ đầu tiên và ví dụ bashthứ hai trong bất kỳ thứ gì được trỏ tới /bin/sh, đó là vỏ POSIX yêu cầu một đối số được truyền vào chỉ định biến bạn muốn đặt đầu vào. Thay đổi shebang để #!/bin/bashsửa lỗi này.


Quan sát tốt @Chris! Điều đó làm việc. Nghĩ rằng tôi sẽ đọc lên một chút về sự khác biệt giữa shbash.
đảo ngược

Thật bất thường! Tôi có thể xem lại /bin/shbash, nhưng nghĩ rằng tôi chỉ cần sử dụng bash trực tiếp từ bây giờ, để tránh sự mơ hồ. Cảm ơn :)
đảo ngược

Các shell tương tác thường xuyên khác với các shell script trong bộ đệm của đầu ra của chúng. Đọc từ các ống liên quy trình có thể dẫn đến tất cả các loại hành vi thời gian kỳ lạ nếu lệnh tạo ra bộ đệm đầu ra ghi khi chạy không tương tác.
JesseM

5

Trong cú pháp sh, bạn cần

IFS= read -r REPLY

Một số shell như ksh, bash và zsh cho phép readđược gọi mà không có tên biến nhưng hành vi khác nhau giữa chúng. Xem ví dụ đầu ra của

printf 'te\ st\\\na ' | "$shell" -c 'read; printf "%s\n" "<$REPLY>"'

khác nhau trên tất cả bash, zsh, pdksh và ksh93


Điều đó có lý do tại sao trình bao tôi đang sử dụng không biết tên biến, cảm ơn @Stephane.
đảo ngược
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.