Đường ống & chuyển hướng ưu tiên ràng buộc với các từ chối, kết hợp, vv?


8

Tôi biết về quyền ưu tiên ràng buộc tương đối của các toán tử ';', '&', '&&' hoặc '||'

http://www.gnu.org/software/bash/manual/bashref.html#Lists

nhưng khi các đường ống đi vào bức tranh cùng với '&&', tôi đấu tranh để hiểu sức mạnh ràng buộc và vấp phải một mệnh lệnh chính xác hoặc chỉ bỏ cuộc.

Ưu tiên ràng buộc của '|' là gì và '>' so với ở trên?

Ví dụ khi tôi bị nhầm lẫn:

ls _thumbnails/video.mp4.jpg 2>/dev/null 
    && echo "thumbnail already generated. Not regenerating" \
    && exit \
    || ffmpeg_thumbnail_create video.mp4 2>/dev/null \
    && ls _thumbnails/video.mp4.jpg \
    && echo "Thumbnail successfully created" \
    && exit \
    || echo "Thumbnail creation failed" \
    | tee ~/thumbnails.log

Mục tiêu của những điều trên là tạo ra một hình thu nhỏ nếu và chỉ khi nó chưa xuất hiện (tôi chạy một cronjob hàng ngày). Và tôi không thích số lượng đầu ra khổng lồ của ffmpeg khi không có lỗi (đó không phải là cách Unix). Cũng có những tình huống khác vì vậy đừng bắt đầu cho tôi lời khuyên sử dụng các tuyên bố riêng biệt hoặc các tùy chọn đặc biệt dành riêng cho các chương trình này. Tôi muốn hiểu quyền ưu tiên ràng buộc.


Rất hữu ích - Tôi đánh dấu điều này đúng nếu đó là phản hồi. Chỉ một câu hỏi nữa - làm thế nào để tôi thay đổi quyền ưu tiên? Theo lý thuyết tôi nghĩ {... }nên làm việc. Tôi có thể đã thử nó một cách không hệ thống và không có kết quả như mong đợi.
Sridhar Sarnobat

Câu trả lời:


12

Câu trả lời ngắn gọn là <, >, và các biến thể của họ có quyền ưu tiên cao nhất ràng buộc (chặt chẽ ràng buộc), tiếp theo |, tiếp theo &&||, tiếp theo ;&. Vì vậy, chỉ có echo "Thumbnail creation failed"được dẫn vào tee.

Một câu trả lời dài hơn một chút sẽ chỉ ra rằng ưu tiên cao nhất thực sự là nhóm, có thể được chỉ định bằng dấu ngoặc đơn hoặc dấu ngoặc nhọn. Ví dụ,

A  &&  (B; C)

A  &&  { B; C;}

xấp xỉ tương đương với

if A
then
    B
    C
fi

Ghi chú:

  • Các dấu ngoặc đơn cung cấp cho bạn một subshell; tức là các lệnh BCchạy trong một tiến trình con. Do đó, các lệnh như gán biến hoặc cd sẽ không có hiệu lực trên shell cha. Các lệnh trong dấu ngoặc nhọn chạy trong cùng tiến trình với Alệnh. Do đó, cấu trúc cú đúp A && { B; C;}là gần gũi hơn với những if- then- elsexây dựng.
  • Trong cú pháp cú đúp, phải có khoảng trắng sau dấu {;(hoặc a &hoặc dòng mới) trước dấu }.

Để đọc thêm, hãy xem Toán tử điều khiển và chuyển hướng của shell là gì? khi nào thì 'nếu' không cần thiết? (đặc biệt là câu trả lời của tôi).

Đối với thậm chí nhiều hơn đọc thêm, xem các bash (1) người đàn ôngcác đặc điểm kỹ thuật POSIX / định nghĩa của Shell Command Language , đặc biệt Mục 2.9, Shell CommandsPhần 2.10.2, Shell Rules Grammar . Đây là một nỗ lực để cung cấp một số bối cảnh cho ở trên:

  • Những thứ như

    • myVar=42
    • IFS= read a
    • date
    • cd /some/directory
    • ls -laR dir1 dir2
    • cat foo* > /tmp/allfoo
    • ls -laR dir{1,2}
    • find . -type f -name "foo*" -print > /tmp/output 2> /dev/null
    • > newfile
    • [ -f catfood ]
    • exit

    Tất cả đều được coi là các lệnh đơn giản của Viking.

  • Những thứ như
      đơn giản 1   |   đơn giản 2 và 2   |   simple_command 3
    là những đường ống của NỮA. Ngữ pháp thiết lập các khối xây dựng và xây dựng dựa trên chúng, như là điển hình cho các ngữ pháp chính thức như thế này (và đối với các ngôn ngữ lập trình như C), do đó, một lệnh đơn giản của riêng lẻ được coi là một đường dẫn đường ống, mặc dù nó không chứa một đường ống. Nó không có ý nghĩa (ngữ nghĩa) cho một phép gán biến là một thành phần của một đường ống, nhưng những thứ như x=1 | od -abhoặc ls -laR | z=0có giá trị về mặt cú pháp.
  • Những thứ như
      đường ống 1   &&   đường ống 2   | |   đường ống 3
      được gọi là danh sách của người khác bởi bash và người liệt kê AND-OR liệt kê danh sách của POSIX. Một lần nữa, một đường ống cá nhân khác, hay thậm chí là một lệnh đơn giản riêng lẻ, được coi là một danh sách VÀ VÀ HOẶC, mặc dù nó không chứa AND hoặc OR.
    • Khi bạn nhận được những thứ như
        Danh sách AND-OR 1  &   AND-OR danh sách 2  ;   Danh sách VÀ-HOẶC 3
        danh pháp bắt đầu có một chút không nhất quán. Bash cũng gọi những danh sách này. POSIX gọi chúng là danh sách của chúng tôi Một lần nữa, một danh sách cá nhân VÀ VÀ HOẶC, một đường dẫn đơn giản, hay thậm chí là một lệnh đơn giản, riêng lẻ, được coi là một danh sách khác, mặc dù nó không chứa a &hoặc a ;.
      • Những thứ như
          ( ghép_list )
            {  ghép_list ;}
            và các lệnh điều khiển luồng ( for,  if- then- else,  while, vv) được gọi là “lệnh hợp chất”. 
          • Trong ví dụ trên, nó có thể làm cho ý nghĩa nhất để giải thích A, BClà đường ống. Hãy nhớ rằng, một đường ống của người Viking có thể là một lệnh đơn giản cá nhân nó không cần phải chứa một đường ống.


            1
            Cảm ơn đã giải thích chi tiết về vai trò của (.. ){.. }. Tôi đã kết luận từ kinh nghiệm tồi tệ trước đây rằng dấu ngoặc tròn chỉ được sử dụng trong ngữ cảnh của "các lệnh động" (nghĩa là $(.. )) vì tôi hầu như không thể khiến chúng làm bất cứ điều gì liên quan đến sự kết hợp.
            Sridhar Sarnobat
            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.