2013-02-14 36 views
15

Tôi muốn chạy lệnhLàm thế nào để thoát khỏi tìm exec nếu nó không thành công trên một trong các tập tin

find some/path -exec program \{} \; 

nhưng tôi muốn các lệnh find để bỏ càng sớm càng lệnh

program \{} 

không thành công trên bất kỳ tệp nào được tìm thấy.

Có cách nào đơn giản để thực hiện việc này không?

+0

Liên quan: http://unix.stackexchange.com/questions/62880/how-to-stop-the-find-command-after-first-match – kojiro

Trả lời

1

Bạn có thể đường ống đầu ra từ find để trình con khác và sử dụng while/break:

find some/path | while read f 
do 
    program $f 
    if [ $? -ne 0 ] 
    then 
     break 
    fi 
done 
+1

Sẽ tốt hơn nếu bạn chỉ làm 'if! chương trình $ f; sau đó phá vỡ ... '. Bạn cũng có thể delimit trên NUL thay vì newlines bằng cách sử dụng '-print0' và read -d '', an toàn hơn. – kojiro

+1

Biến thể này áp dụng đề xuất an toàn từ @kojiro, điều quan trọng nếu tệp chứa dấu cách. Đối với điều đó bạn cũng cần báo giá xung quanh '$ f'. (và lưu ý nó sử dụng bash-cụ thể '$ '''). Nó cũng nhỏ hơn: 'find path -print0 | trong khi đọc -d $ '\ 0' f; làm lệnh "$ f" || phá vỡ; done' – darque

2

tôi nghĩ rằng nó không thể đạt được những gì bạn muốn, chỉ với find -exec.

Việc thay thế gần nhất sẽ được để làm ống find để xargs, như thế này:

find some/path -print0 | xargs -0 program 

hoặc

find some/path -print0 | xargs -0L1 program 

này sẽ bỏ nếu chương trình kết thúc với một trạng thái thoát khác không

  • print0 được sử dụng để các tệp có dòng mới trong tên có thể bị xử lý
  • -0 là cần thiết khi -print0 được sử dụng
  • các L1 nói xargs chương trình để thực hiện chương trình với một đối số tại một thời điểm (mặc định là để thêm tất cả lập luận trong một thực thi duy nhất của chương trình)

Nếu bạn chỉ có tên tập tin lành mạnh, bạn có thể đơn giản hóa như thế này:

find some/path | xargs program 

hoặc

find some/path | xargs -L1 program 

Cuối cùng, nếu chương trình thực hiện nhiều đối số, bạn có thể sử dụng -i kết hợp với {}. Ví dụ.

find some/path | xargs -i program param1 param2 {} param4 
4

Bên cạnh những câu trả lời tốt khác, GNU tìm (ít nhất) có một vị -quit:

find path -other -predicates \(-exec cmd {} \; -o -quit \) 

Các -quit vị là certainly non-standard và không tồn tại trong BSD find.

+2

Điều này là gần với những gì tôi cần nhưng tôi cần phải thoát ra với một trạng thái thoát nonzero nếu điều này không thành công (phần thứ hai của vị từ). – Lucas

0
% _find_trap() { 
> _find_pid="${1}" ; _find_ops="${2}" ; _find_trigger="${3}" 
> shift 3 && set -- "${@}" 
> trap 'kill -s INT "-${_find_pid}" \ 
>  unset _find_pid _find_ops _find_trigger ; set - \ 
>  1>&2 printf "%s" "find killed due to trap" \ 
>  exit [CODE] ' TRAP 
> while { sh -c "${_find_ops} ${@}"} { 
> [ "${_find_trigger}" ] && { kill -s TRAP "-${_find_pid}" ; break ; } 
> ... 
> } 
> export -f _find_trap ; find . -execdir _find_trap \"$$\" \"${cmds}\" \ 
> \"${testable_trigger}\" "{}" + 
0

Dưới đây là ví dụ của tôi cho một "xây dựng hệ thống", mà dừng lại sau khi chạm đầu tiên lỗi biên dịch (dựa trên câu trả lời Kojiro, mà không làm việc exaclty cho tôi):

(Nhu cầu dấu ngoặc đơn thoát là thật, tôi biết điều đó.)

find -name '*.cpp' \(-print -a -exec g++ -c {} \; -o -quit \) 

Tôi muốn xây dựng một thư viện tĩnh về cơ bản tất cả các tệp C++ nằm trong thư mục hiện tại và bên dưới.

Trước khi chạy trình biên dịch Tôi muốn có file -print -ed, sau đó -exec -ed, nhưng khi nó không thành công (và lá lỗi trên stderr, nó nên -quit.

-a là như &&-o cũng giống như || trong vỏ hoặc C.

Nếu không có dấu ngoặc đơn, GNU tìm "tối ưu hóa" truy vấn, bằng cách cố gắng điều kiện có thể xảy ra nhất đầu tiên, đó là - tôi đoán -. -quit

Các vấn đề liên quan