Không, vấn đề là bạn đang hiểu sai về cách thức hoạt động của đường ống.
Trong các đường ống Unix, dữ liệu chảy từ trái sang phải (cùng hướng với văn bản bằng tiếng Anh) - đầu ra của chương trình đầu tiên trở thành đầu vào của chương trình thứ hai. Nhưng các đường ống là đơn hướng; đầu ra của chương trình thứ hai không được gửi đến chương trình đầu tiên.
Khi bạn chạy sml file.sml | echo -e "\004"
, bạn không lặp lại Ctrl + D đến sml
. Thay vào đó, bạn đang chuyển sml
đầu ra của echo
lệnh tới lệnh - nơi nó bị loại bỏ, vì echo
không sử dụng stdin.
- bàn phím →
sml file.sml
→ echo -e "\004"
→ màn hình
Nỗ lực thứ hai của bạn sml file.sml | sleep 2 ; echo -e "\004"
, có một vấn đề tương tự - đầu ra của sml
được gửi đến sleep
(cũng loại bỏ đầu vào mà nó nhận được). Tuy nhiên, có một vấn đề khác: echo
lệnh bây giờ không phải là một phần của đường ống; bạn có thể nói rằng |
có một ưu tiên cao hơn ;
. (Bạn có thể nhóm các lệnh bằng cách sử dụng dấu ngoặc đơn ; vd a | (b; c; d)
.)
- bàn phím →
sml file.sml
→ sleep 2
→ màn hình
- bàn phím →
echo -e "\004"
→ màn hình
Như đã nói ở trên, cả hai lần thử đều được viết sai hướng . Nếu bạn muốn gửi \004
nhân vật đến sml
, đường ống nên được viết như thế này:
echo -e "\004" | sml file.sml
trong đó, sml
đầu ra của nó đi đến màn hình, nơi nó nên.
Có một vấn đề khác , tuy nhiên. Bạn cũng đang nhầm lẫn giữa CtrlDphím nhấn với sự kiện "kết thúc đầu vào" .
Việc dịch CtrlDthành "kết thúc đầu vào" chỉ xảy ra ở lớp thiết bị đầu cuối - nói cách khác, chỉ khi bạn nhập ký tự Ctrl + D vào cửa sổ đầu cuối. Tuy nhiên, khi bạn sử dụng echo -e "\004"
trong một đường ống, nó không được dịch tự động thành "kết thúc đầu vào"; thay vào đó, byte thực tế 004 [bát phân] được viết.
Nếu bạn thực sự muốn nói với chương trình rằng không còn đầu vào nữa, thì đừng viết gì cả . Sử dụng một lệnh kết quả đầu ra không có gì - ví dụ, echo -n
hoặc true
, hoặc chỉ cần chuyển hướng đầu vào từ các /dev/null
tập tin.
echo -n | sml file.sml
sml file.sml < /dev/null