thoát ra khỏi tìm nếu một -exec thất bại


14

Có cách nào để viết một findcái để nó bị hỏng nếu một trong các -execthao tác không thành công trên một tệp không?

Ví dụ: ( javacđược sử dụng thuận tiện như một chương trình có thể trả về mã thoát 1 trên một số tệp và không vì lý do nào khác):

$ echo "public classXX A{}" >> A.java
$ echo "public class B{}" >> B.java
$ find . -iname \*.java -exec javac {} \;
./A.java:1: error: class, interface, or enum expected
public classXX A{}
       ^
1 error

Trong ví dụ trên, mặc dù exectrên tệp A.javakhông thành công (và trả về mã thoát là 1), findlệnh cũng được tiến hành và biên dịch tệp B.java. Có cách nào để thoát ra findhay tôi nên sử dụng một số hình thức forthay thế?

Phiên bản tìm kiếm của tôi:

$ find -version  | head -1
find (GNU findutils) 4.4.2

Câu trả lời:


5

Tôi nghĩ...

find ... -exec sh -c 'cmd "$0" || kill $PPID' \{\} \;

... nên làm thủ thuật cho bất kỳ find.


Cảm ơn @Gilles. Làm gì $0?
mikeerv

1
$0là đối số đầu tiên sh -c( $1là đối số thứ hai, v.v.) - thông thường tên của chương trình đang được thực thi, nhưng ở đây bạn đang thực thi một đoạn mã và truyền tên tệp đang được xử lý như $0ý nghĩa (ví dụ: bạn dễ dàng thấy nó trong ps). Có một trường phái tư tưởng (mà rõ ràng tôi không thuộc về) nói rằng $0luôn luôn có thể thực thi được và bạn nên viết sh -c 'cmd "$1" …' sh {}hoặc một số thứ như vậy.
Gilles 'SO- đừng trở nên xấu xa'

@Gilles - Khá bóng bẩy. Cảm ơn rất nhiều. Tôi đã tìm ra nó trong xe trên đường đến trường mầm non, nhưng tôi phải suy nghĩ về nó trong vài phút. Thật thông minh - Tôi sẽ sử dụng nó. Điều thực sự đã nhấp vào nó đối với tôi là một bản chỉnh sửa mà tôi nhớ đã đọc về Stephane trên một trong những bài đăng của riêng bạn, trong đó anh ấy đã thêm một find-sh $0phần cuối của một findtuyên bố. Điều này có vẻ hữu ích hơn theo quan điểm của tôi, mặc dù tôi đoán đó là những gì bạn về sau về lâu dài mới là vấn đề quan trọng nhất.
mikeerv

Nó không hoạt động cho trường hợp trên. Sau khi find . -iname \*.java -exec sh -c 'javac "${0}" || kill '$$ {} \;tệp A.javakhông thành công và, tệp B.java sẽ được biên dịch.
Marcus Junius Brutus

@MarcusJuniusBrutus - Tôi đã sửa nó. Tôi nên xem bình luận của bạn sớm hơn. Một lần nữa xin lỗi.
mikeerv

4

Ít nhất với GNU findbạn có thể sử dụng:

find ... -exec ... -o -quit

Tôi dường như gặp khó khăn trong việc làm rõ nơi thực thi dừng lại và -o bắt đầu. Cả hai find . -iname \*.java -exec javac {} -o -quit \;find . -iname \*.java -exec javac {} \; -o -quit \;thất bại (theo những cách khác nhau)
Marcus Junius Brutus

@MarcusJuniusBrutus \;là cần thiết tại và của -exec(tức là trước đây -o -quittrong trường hợp này) nhưng có thể không ở đâu khác.
Hauke ​​Laging

2
Sử dụng -exec ... -o -quitkhông làm việc cho tôi. Nó không xử lý bất kỳ tập tin. Tuy nhiên dòng này hoạt động: find . -iname \*.java -not -exec javac '{}' \; -quit: -quitđược gọi nếu -execlà sai, tức là. trả về với giá trị khác không.
savanto

find . -iname \*.java -exec javac {} \; -o -quitquá, không thể xử lý bất kỳ tập tin. Kỳ lạ thay, find . -iname \* -exec echo 'foo' \; -o -quit không "quá trình" các tập tin.
Marcus Junius Brutus

0

Tham khảo findhướng dẫn của bạn . Câu trả lời của @ Hauke ​​thúc đẩy tôi tìm kiếm và tìm kiếm của QNX có một -aborttùy chọn có vẻ giống với -quittùy chọn GNU . Nó hoạt động với tôi miễn là tôi sử dụng \(\)biểu thức nhóm:

find . -mtime -4 -name <pattern> \( -exec my_cmd {} \; -o  -abort \) 

Lưu ý: không có parens, nó sẽ hủy bỏ tập tin đầu tiên.

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.