2013-02-14 3 views
15

Chcę uruchomić polecenieJak wyjść z -exec znaleźć, jeśli nie na jednym z plików

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

ale chcę polecenie Znajdź, aby zakończyć jak najszybciej polecenia

program \{} 

kończy się niepowodzeniem na każdym znalezionym pliku.

Czy istnieje prosty sposób na zrobienie tego?

+0

Powiązane: http://unix.stackexchange.com/questions/62880/how-to-stop-the-find-command-after-first-match – kojiro

Odpowiedz

1

Można by rura wyjście z find do innego podproces i używać while/break:

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

Byłoby lepiej po prostu zrobić 'if! program $ f; następnie zepsuć ... '. Można również ograniczać przez NUL zamiast nowych linii używając '-print0' i read -d '', co jest bezpieczniejsze. – kojiro

+1

Ten wariant stosuje sugestie bezpieczeństwa z @kojiro, które są ważne, jeśli pliki zawierają spacje. Do tego potrzebne są również notowania wokół '$ f'. (i zauważ, że używa specyficznego dla bash '$ '''). Jest także mniejszy: 'find path -print0 | podczas odczytu -d $ '\ 0' f; wykonaj polecenie "$ f" || przerwa; done' – darque

2

myślę, że nie jest możliwe, aby osiągnąć to, co chcesz, tylko z find -exec.

Najbliżej alternatywą byłoby zrobić rurę find do xargs, tak:

find some/path -print0 | xargs -0 program 

lub

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

To rzucić jeśli Program kończy działanie z kodem wyjścia niezerowej

  • Użyto print0, aby pliki z znakami nowej linii Nazwy mogą być obsługiwane
  • -0 jest konieczne, gdy -print0 służy
  • L1 mówi xargs program do wykonywania programu z jednym argumentem na raz (domyślnie jest dodanie wszystkie argumenty w jednym realizacji programu)

Jeśli masz tylko rozsądnych nazwy plików, można uprościć tak:

find some/path | xargs program 

lub

find some/path | xargs -L1 program 

Wreszcie, jeśli program przyjmuje więcej niż jeden argument, można użyć -i w połączeniu z {}. Na przykład.

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

Oprócz innych drobnych odpowiedzi, GNU znaleźć (przynajmniej) ma -quit predykat:

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

-quit orzecznikiem jest certainly non-standard i nie istnieje w BSD znalezisku.

+2

Jest to zbliżone do tego, czego potrzebuję, ale muszę wyjść z niezerowym kodem zakończenia, jeśli to się nie powiedzie (druga część predykatu). – 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

Oto mój przykład o „systemie build”, który zatrzymuje się po uderzeniu pierwszy błąd kompilatora (na podstawie odpowiedzi Kojiro, który nie działa exaclty dla mnie):

(Potrzeba unikanie nawiasów jest prawdziwe, wiem, że to boli.)

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

Chcę zbudować statyczną bibliotekę zasadniczo wszystkich plików C++ znajdujących się w bieżącym katalogu i poniżej.

Przed uruchomieniem kompilatora chcę mieć plik -print -ed, potem -exec -ed, ale gdy nie powiedzie się (i pozostawia na stderr błędy, powinien -quit.

-a jest jak && i -o jest jak || w skorupkach lub C.

bez nawiasów, GNU find „optymalizuje” kwerenda, próbując najbardziej prawdopodobny warunek pierwszy, który jest - myślę, -. -quit