вирватися з пошуку, якщо -exec не вдається


14

Чи є спосіб записати findтак, щоб воно порушилось, якщо одна з -execоперацій не відбудеться у файлі?

Напр. ( javacЗручно використовувати як програму, яка може повернути вихідний код 1 у деяких файлах і без жодної іншої причини):

$ 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

У наведеному вище прикладі, хоча execфайл у файлі A.javaне вдався (і повернув вихідний код 1), findкоманда продовжувала і компілювала файл B.java. Чи є спосіб вийти з ладу findчи я повинен forзамість цього використовувати якусь форму ?

Моя версія пошуку:

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

Відповіді:


5

Я думаю...

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

... повинен робити трюк для майже будь-якого find.


Дякую @Gilles Що робить $0?
mikeserv

1
$0це перший аргумент sh -c( $1є другим і т. д.) - умовно назва програми, яка виконується, але тут ви виконуєте фрагмент і передаєте ім'я файлу, яке обробляється, як $0має певний сенс (наприклад, ви легко бачите це в ps). Існує школа думки (до якої я, очевидно, не належу), яка стверджує, що $0завжди має бути виконуваною, і ви повинні написати sh -c 'cmd "$1" …' sh {}або щось таке.
Жил 'ТАК - перестань бути злим'

@Gilles - досить гладкий. Дуже дякую. Я зрозумів це в машині по дорозі до дошкільного закладу, але мені довелося думати про це кілька хвилин. Це розумно - я буду його використовувати. Що насправді натиснув на мене, це редакція, яку я згадав, читаючи Стефана в одному з ваших власних дописів, в якому він додав а find-sh $0в кінці findзаяви. На мою думку, це здається більш корисним, хоча, мабуть, найбільше важливо саме те, що ти хочеш, з часом.
mikeserv

Це не працює для вищевказаної справи. Після того, як find . -iname \*.java -exec sh -c 'javac "${0}" || kill '$$ {} \;файл A.javaвиходить з ладу, і все-таки файл B.java збирається.
Маркус Юній Брут

@MarcusJuniusBrutus - я це виправив. Я повинен був бачити ваш коментар раніше. Знову вибачте.
mikeserv

4

Принаймні з GNU findви можете використовувати:

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

Здається, у мене виникають проблеми, щоб зрозуміти, де зупиняється виконавець і починається -o. І те, find . -iname \*.java -exec javac {} -o -quit \;і find . -iname \*.java -exec javac {} \; -o -quit \;невдало (по-різному)
Маркус Юніус Брут

@MarcusJuniusBrutus \;потрібен в і -exec(тобто раніше -o -quitв цьому випадку), але може бути ніде більше.
Hauke ​​Laging

2
Використання -exec ... -o -quitдля мене не працює. Він не обробляє жодних файлів. Однак ця лінія працює: find . -iname \*.java -not -exec javac '{}' \; -quit: -quitвикликається , якщо -execпомилково, тобто. повертається з ненульовим рівнем.
savanto

find . -iname \*.java -exec javac {} \; -o -quitтакож не обробляє жодні файли. Як find . -iname \* -exec echo 'foo' \; -o -quit не дивно, чи "обробляє" файли.
Маркус Юніус Брут

0

Зверніться до findпосібника. @ Відповідь Хоуке мотивував мене подивитися, і пошук QNX має -abortваріант, схожий на -quitваріант GNU . Це працює для мене за умови використання \(та \)групування виразів:

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

Примітка: без паронів він перериває перший файл.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.