Jeg prøver å kjøre følgende kommando:
find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar "{}" +
Dette returnerer en feil:
find: missing argument to -exec
Jeg kan ikke se hva som er galt med denne kommandoen, siden det ser ut til å matche mannssiden :
-exec-kommando {} +
Denne varianten av -exec-alternativet kjører den spesifiserte kommandoen på de valgte filene, men kommandolinjen er bygd ved å legge til hvert valgte filnavn på slutten; det totale antallet innkallinger til kommandoen vil være mye mindre enn antall samsvarende filer. Kommandolinjen er bygget på omtrent samme måte som xargs bygger sin kommandolinjer. Bare en forekomst av «{}» er tillatt i kommandoen. Kommandoen utføres i startkatalogen.
Jeg prøvde også:
find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar {} + find a/folder b/folder -name *.c -o -name *.h -exec "grep -I foobar" {} + find a/folder b/folder -name *.c -o -name *.h -exec "grep -I foobar" "{}" + find a/folder b/folder -name "*.c" -o -name "*.h" -exec grep -I foobar "{}" + find a/folder b/folder \( -name *.c -o -name *.h \) -exec grep -I foobar "{}" + find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar "{}" \+
Kommentarer
Svar
Det var flere problemer med forsøkene dine, inkludert backticks brukt i stedet for anførselstegn (fjernet i senere redigeringer av spørsmålet), manglende anførselstegn der det kreves, ekstra anførselstegn der de er ubrukelige, mangler parenteser til gruppen -o
klausuler og forskjellige implementeringer av find
brukt (se kommentarene og chatten for detaljer).
Uansett kan kommandoen forenkles slik:
find a/folder b/folder -name "*.[ch]" -exec grep -I foobar {} +
eller, hvis du bruker en arkaisk GNU-finnversjon, bør dette alltid fungere:
find a/folder b/folder -name "*.[ch]" -exec grep -I foobar {} \;
Kommentarer
- Ups, de var ment å være sitater ikke backticks.
- Sitater ville være ubrukelige som
{}
har ingen spesifikk betydning for skallet. - Fra finn man-sider: » Strengen ‘ { } ‘ er erstattet av det nåværende filnavnet som behandles overalt det forekommer i argumentene til kommandoen, ikke bare i argumenter der det er alene, som i noen versjoner av find. Begge disse konstruksjonene må kanskje rømmes (med en ‘ \ ‘) eller siteres for å beskytte dem mot utvidelse av skallet. »
- Jeg leste det faktisk på manualsiden, men faktum er at det ikke er noe skall jeg ‘ er klar over som krever sitering av krøllete bukseseler. Hvilket skall bruker du?
- bash. Med eller uten anførselstegn får jeg uansett feilen.
Svar
“mangler argument til -exec
”betyr vanligvis at argumentet til – exec
mangler terminatoren. Terminatoren må enten være et argument som bare inneholder tegnet ;
(som må siteres i en shell-kommando, så det er vanligvis skrevet \;
eller ";"
), eller to påfølgende argumenter som inneholder {}
og +
.
Stephane Chazelas har identifisert at du bruker en eldre versjon av GNU-funn som ikke støtter -exec … {} +
, bare -exec {} \;
.Selv om GNU var en sen adopterer av -exec … {} +
, anbefaler jeg at du får en mindre antikk verktøypakke (for eksempel Cygwin , som inkluderer git og mye mer, eller GNUwin32 , som mangler git, men som ikke har den dårlige medarbeideren som prøver å bruke Linux -but-we-impose-windows vibe som Cygwin gir). Denne funksjonen ble lagt til i versjon 4.2.12 for over 9 år siden (det var den siste identifiserte funksjonen for å lage GNU find
POSIX-kompatibel).
Hvis du vil holde deg til et eldre GNU-funn, kan du bruke -print0
med xargs -0
for å få en lignende funksjonalitet: gruppert kommandokjøring, som støtter vilkårlige filnavn.
find a/folder b/folder -name "*.c" -o -name "*.h" -print0 | xargs -0 grep -I foobar /dev/null
Sitat alltid jokertegnene på find
kommandolinje. Hvis ikke du kjører denne kommandoen fra en katalog som inneholder .c
filer, vil den ikke siterte *.c
woul d utvides til listen over .c
filer i den aktuelle katalogen.
Legger til /dev/null
i grep
kommandolinje er et triks for å sikre at grep alltid vil skrive ut filnavnet, selv om find
tilfeldigvis finner en enkelt kamp. Med GNU find er en annen metode å overføre alternativet -H
.
Kommentarer
- Hva gjør du mener med dårlig ansatt-prøver-å-bruke-linux-men-vi-pålegger-windows-stemning som cygwin gir?
- GNUwin32 har ikke ‘ ikke forventet 🙁
- Se kommentarene mine til spørsmålet.
- Sitatene rundt semi fungerte fra et package.json-skript.
Svar
Hvis en kommando som
find a/folder b/folder -name "*.c" -o -name "*.h" -exec grep -I foobar {} +
returnerer feil
find: missing argument to -exec
den sannsynlige årsaken er for gammel GNU find
som ikke støtter syntaks -exec mycommand {} +
I så fall er erstatning med lav ytelse å kjøre -exec mycommand {} \;
som vil kjøre mycommand
en gang for hvert funnet mål i stedet for å samle flere mål og kjører mycommand
bare en gang.
GNU find
doe støtter ikke f.eks.
find . -type f -and -name "*.ttf" -exec cp {} ~/.fonts +
fordi GNU find
støtter bare bokstavelig kombinasjon {} +
i stedet for mer generisk {} additional parameters +
. Vær oppmerksom på at det ikke kan være noe mellom klammeparentesene og +
-tegnet. Hvis du prøver dette, får du den samme feilen:
find: missing argument to -exec
Løsningen er å bruke syntaks {} additional parameters \;
fungerer, men vil utføre kommandoen en gang for hvert funnet mål. Hvis du trenger mer ytelse med GNU find
, må du skrive et wrapper-skript som kan legge til tilleggsparametere til de gitte argumentene. Noe som
#!/bin/bash exec mycommand "$@" additional parameters
burde være bra nok. Eller hvis du ikke vil opprette midlertidig fil, kan du bruke en-linje til å endre rekkefølgen på parametere som dette:
find . -type f -and -name "*.ttf" -exec bash -c "mycommand "$@" extra arguments" {} +
som vil kjøre mycommand {list of ttf files} extra arguments
. Vær oppmerksom på at det kan hende du må dobbeltegne spesialtegn for bash etter -c
-flagget.
Kommentarer
- (1) Den delen av det ovennevnte som faktisk svarer på spørsmålet, var allerede gitt av andre mennesker. (2) Det du beskriver er ikke en feil eller mangel på GNU
find
, men den riktige oppførselen spesifisert av POSIX . - +1 Endelig, noen som svarer på hvorfor flere parametere ikke fungerer ‘! Det virker som en mangel i POSIX-definisjonen.
- Hvis du ‘ har GNU
find
du ‘ har sannsynligvis fått GNUcp
. I dette tilfellet kan dufind ... -exec cp --target-directory ~/.fonts {} +
for å beholde{}
på slutten av kjøringsstrengen.
Svar
find . -type f -perm 0777 -exec chmod 644 {}\;
fikk feil find: missing argument to ``-exec"
.
Å legge til mellomrom mellom {}
og \
fikset det:
find . -type f -perm 0777 -print -exec chmod 644 {} \;
Kommentarer
- Det er ikke noe slikt problem i
find
kommandoen i det aktuelle spørsmålet. - I spørsmål er det ikke greit at jeg forsto det, men problemet er det samme » finn: mangler argument til « -exec ‘ «, Problem kan oppstå av annen-2 grunn, svarte jeg fordi jeg så samme problemstilling.
- @Kusalananda god sorg, noob ga en løsning for den rapporterte feilen som er angitt av OP i både tittelen og selve spørsmålet.
- @bvj Spørsmålet handler eksplisitt med
+
form av-exec
alternativet tilfind
. Dette svaret korrigerer et problem som brukeren som stiller spørsmålet ikke har.
Svar
Jeg hadde min andel av hodepine med exec-syntaksen tidligere. de fleste dager nå foretrekker jeg den finere bash-syntaksen:
for f in `find a/folder b/folder -name "*.[ch]"`; do grep -I foobar $f; done
Det har noen begrensninger når du vil behandle filene som en gruppe, ettersom hver blir evaluert serielt, men du kan rense utdataene andre steder helt fint
Kommentarer
- Selv om dette har en tendens til å fungere, er det betydelig mindre nyttig enn pure-find-versjonen fordi det kan ikke håndtere filer med mellomrom i navnet riktig.
- Nei, ikke ‘ ikke gjør dette. Dette går i stykker så snart filene inneholder mellomrom og andre «rare» tegn. Dette er også mer komplekst og langsommere enn
find … -exec … \;
, så ‘ er ingen grunn til å bruke dette selv om du vet at filnavnene dine er tamme. - dette var nyttig for min situasjon der jeg trengte å kjøre flere linjer med logikk basert på filnavnene (som å fjerne tegn, lage kataloger og deretter flytte filene). Å prøve å finne å gjøre flere ting i en
exec
var for mye hodepine i de 5 minuttene jeg ønsket å bruke på dette. Filnavnene mine var tamme, og dette løste problemet mitt 🙂
+
på slutten?find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar '{}' \+
find
. Selv om-exec cmd {} +
-varianten er POSIX og har vært tilgjengelig siden 80-tallet, fant GNU bare den (relativt) nylig (2005). Hva fortellerfind --version
deg?-exec {} +
ble lagt til i 4.2.12 i 2005. I eldre GNU-funn kan du bruke (ikke-POSIX)-print0 | xargs -r0
for å få noe lignende.4.1
er fra 1994.-name
mønsteret argumenter bør siteres:-name "*.c" -o -name "*.h"
. Dette stemmer, selv om det ikke er relatert til-exec
feilen. Du vil legge merke til at alle de andre svarene gir jokertegnene sitater, selv om bare Gilles nevner det. … (forts.)-name "*.[ch]"
uten forklaring. Dette har fordelene med å forenkle kommandolinjen og spesifikt eliminere-o
. Finn uttrykk som involverer-o
er vanskelig å få rett. Din er feil; hvis kommandoen din er løst slik at den ikke feiler (som i Gilles svar), vil den kjøregrep
bare på.h
filer. Du må gjøre'(' -name '*.c' -o -name '*.h' ')'
.