Kịch bản cổ điển với Toán tử ưu tiên, bạn có một dòng như:
(cd ~/screenshots/ && ls screenshot* | head -n 5)
Và bạn không biết nếu nó được phân tích cú pháp ((A && B) | C)
hay (A && B | C)
...
Các tài liệu gần như chính thức được tìm thấy ở đây không liệt kê các đường ống trong danh sách vì vậy tôi không thể chỉ cần kiểm tra trong bảng.
Hơn nữa, trong bash, (
không chỉ để thay đổi thứ tự các hoạt động mà còn tạo ra một mạng con , vì vậy tôi không chắc chắn 100% dòng này tương đương với dòng trước:
((cd ~/screenshots/ && ls screenshot*) | head -n 5)
Tổng quát hơn, làm thế nào để biết AST của một dòng bash? Trong python tôi có một chức năng cung cấp cho tôi cây để tôi có thể dễ dàng kiểm tra lại thứ tự hoạt động.
bash
đang sử dụng một trình phân tích cú pháp yacc chứ không phải một số thứ đặc biệt; nếu bạn chạy yacc -v
nó thông qua nó sẽ cung cấp cho bạn y.output
một ngữ pháp tốt cho thấy điều đó &&
và ||
kết hợp các danh sách, và danh sách cuối cùng được tạo thành từ các đường ống dẫn (chứ không phải ngược lại); tl; dr; A && B | C
là giống như A && { B | C; }
, như mong đợi. Đừng giả sử bất kỳ thứ tự thực hiện giữa B
và C
; các lệnh trong một đường ống được chạy song song .
[...]
các bài kiểm tra và $((...))
đánh giá số học; đặc biệt, ||
và &&
như được sử dụng với danh sách lệnh trong ngôn ngữ shell có cùng mức độ ưu tiên , không giống như các toán tử tương ứng trong C
hoặc trong đánh giá số học (nơi &&
liên kết chặt chẽ hơn ||
).
|
chỉ là một trình kết nối phù hợp với thiết bị xuất chuẩn LHS cho stdin RHS. Vì vậy, nếucd
lệnh trong ví dụ của bạn thất bại, nó sẽ không gửi đầu rahead
, nhưnghead
thực tế vẫn sẽexecute
, phân tích không có gì và không trả lại đầu ra.