A következő parancsot próbálom futtatni:

find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar "{}" + 

Ez hibát eredményez:

find: missing argument to -exec 

Nem látom, hogy mi a baj ezzel a paranccsal, mivel úgy tűnik, hogy egyezik a man oldallal :

-exec parancs {} +

Az -exec opciónak ez a változata a megadott parancsot futtatja a kijelölt fájlokon, de a parancssor úgy épül fel, hogy minden egyes kiválasztott fájlnevet hozzáfűz a végéhez; a parancs meghívásainak teljes száma jóval kevesebb lesz, mint az egyeztetett fájlok száma. A parancssor nagyjából ugyanúgy épül fel, mint az xargs parancssorok. A parancsban csak egy “{}” példány engedélyezett. A parancs a kezdő könyvtárban kerül végrehajtásra.

Próbáltam:

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 "{}" \+ 

Megjegyzések

  • Megpróbált-e elmenekülni a + a végén? find a/folder b/folder -name *.c -o -name *.h -exec grep -I foobar '{}' \+
  • Lehet, hogy a GNU find régi verzióját használja. Noha a -exec cmd {} + variáns POSIX, és a 80-as évek óta elérhető, a GNU find csak a közelmúltban (2005-ben) tette hozzá. Mit mond neked a find --version?
  • @Koveras, akkor ez lenne az. A -exec {} + 2005-ben 4.2.12-ben került hozzáadásra. Régebbi GNU-leleteknél a (nem POSIX) -print0 | xargs -r0 -t használhatja valamire. hasonló. 4.1 1994-ből származik.
  • JRFerguson rámutatott (egy törölt válaszban), hogy a -name minta az argumentumokat idézni kell: -name "*.c" -o -name "*.h". Ez igaz, bár nem kapcsolódik a -exec hibához. Észre fogja venni, hogy az összes többi válasz idézőjelbe helyezi a helyettesítő karaktereket, bár csak Gilles említi. … (Folytatás)
  • (folytatás) … jlliagre válasza magyarázat nélkül összezúzza a névkifejezést -name "*.[ch]" -re. Ennek előnyei a parancssor egyszerűsítése és konkrétan a -o megszüntetése. A -o kifejezéseket nehéz megtalálni. A tied téved; ha a parancsod javítva van, így nem hibázik (mint Gilles válaszában), akkor grep csak a .h fájlokat. Meg kell tennie '(' -name '*.c' -o -name '*.h' ')'.

Válasz

számos probléma a próbálkozásokkal, beleértve az idézőjelek helyett használt háttérjeleket (eltávolítva a kérdés későbbi szerkesztéseiben), hiányzó idézőjelek, ahol szükségesek, extra idézőjelek, ahol haszontalanok, hiányzó zárójelek a -o záradékok és a find különböző megvalósításai (lásd a megjegyzéseket és a csevegést a részletekért).

A parancs így is egyszerűsíthető:

find a/folder b/folder -name "*.[ch]" -exec grep -I foobar {} + 

vagy, ha archaikus GNU keresési verziót használ, ennek mindig működnie kell:

find a/folder b/folder -name "*.[ch]" -exec grep -I foobar {} \; 

Megjegyzések

  • Hoppá, idézőjeleknek, nem pedig backtickeknek szánták őket.
  • Az idézetek haszontalanok lennének, mivel {} -nek nincs külön jelentése a héj számára.
  • A man oldalak kereséséből: ” A string ‘ { } ‘ is helyébe az aktuális fájlnév kerül, amelyet mindenhol feldolgoznak, a parancs argumentumaiban fordul elő, nemcsak azokban az argumentumokban, ahol egyedül van, mint a find egyes verzióiban. Előfordulhat, hogy mindkét konstrukciót el kell kerülni (‘ \ ‘), vagy meg kell idézni, hogy megvédje őket a héj általi terjeszkedéstől. div id = “340c16de68”>

  • Ezt valóban olvastam a kézi oldalon, de tény, hogy nincs héj, amiről ‘ tudom ehhez meg kell idézni a göndör zárójeleket. Milyen héjat használsz?
  • bash. Idézetekkel vagy anélkül a hibát mindenképpen megkapom.
  • Válasz

    “hiányzó argumentum a -exec ”általában azt jelenti, hogy a – exec argumentumnak hiányzik a terminátora. A terminátornak vagy argumentumnak kell lennie, amely csak az ; karaktert tartalmazza (amelyet egy shell parancsban kell idézni, így általában \; vagy ";"), vagy két egymást követő argumentum, amely {} és +.

    Stephane Chazelas megállapította, hogy a GNU régebbi verzióját használja, amely nem támogatja a -exec … {} +, csak -exec {} \;.Bár a GNU a -exec … {} + késői alkalmazója volt, azt javaslom, hogy szerezzen be egy kevésbé antik eszközcsomagot (például Cygwin , amely magában foglalja a git-et és még sok minden mást, vagy a GNUwin32 , amelyből hiányzik a git, de nincs meg a rosszul alkalmazott-próbálkozó-linux -but-we-impose-windows hangulatot, amelyet a Cygwin ad). Ez a funkció több mint 9 évvel ezelőtt került a 4.2.12-es verzióba (ez volt az utolsó azonosított szolgáltatás, amely a GNU find POSIX-kompatibilis).

    Ha ragaszkodni szeretne egy régebbi GNU-kereséshez, használhatja a -print0 elemet a xargs -0 hasonló funkció eléréséhez: csoportosított parancsfuttatás, tetszőleges fájlnevek támogatása.

    find a/folder b/folder -name "*.c" -o -name "*.h" -print0 | xargs -0 grep -I foobar /dev/null 

    Mindig idézze a helyettesítő karaktereket a find parancssor. Ellenkező esetben, ha ezt a parancsot egy .c fájlokat tartalmazó könyvtárból futtatja, a nem idézett *.c woul d ki kell terjeszteni az aktuális könyvtár .c fájljainak listájára.

    A /dev/null hozzáadása a

    parancssori trükk annak biztosítására, hogy a grep mindig kinyomtassa a fájl nevét, még akkor is, ha find véletlenül egyetlen egyezést talál. A GNU kereséssel egy másik módszer a -H opció átadása.

    Megjegyzések

    • Mit csinálsz azt jelenti, hogy rossz alkalmazottal próbálkoznak a linux használatával, de Windows-hangulatot vetünk be, amelyet a cygwin ad?
    • A GNUwin32 nem ‘ nem számít rá 🙁
    • Lásd a kérdéshez fűzött megjegyzéseimet.
    • A félig körüli idézetek egy pack.json szkripten belül működtek.

    Válasz

    Ha egy olyan parancs, mint

    find a/folder b/folder -name "*.c" -o -name "*.h" -exec grep -I foobar {} + 

    hibát ad vissza

    find: missing argument to -exec 

    a valószínű ok túl régi GNU find, amely nem támogatja a szintaxist -exec mycommand {} +. Ebben az esetben az alacsony teljesítményű helyettesítés az -exec mycommand {} \; futtatása, amely minden megtalált célhoz egyszer futtatja a mycommand -t, több cél összegyűjtése helyett. és a mycommand futtatását egyszer.

    Azonban a GNU find őz s nem támogatják pl.

    find . -type f -and -name "*.ttf" -exec cp {} ~/.fonts + 

    mert a GNU find csak a szó szerinti kombinációt támogatja {} + általánosabb {} additional parameters + helyett. Vegye figyelembe, hogy a zárójelek és a + karakter között nem lehet semmi. Ha megpróbálja ezt, ugyanazt a hibát kapja:

    find: missing argument to -exec 

    A megoldás a {} additional parameters \; szintaxis használata működik, de minden megtalált célhoz egyszer végrehajtja a parancsot. Ha nagyobb teljesítményre van szüksége a GNU find használatával, meg kell írnia egy burkoló szkriptet, amely további paramétereket csatolhat a megadott argumentumokhoz. Valaminek

     #!/bin/bash exec mycommand "$@" additional parameters  

    elég jónak kell lennie. Vagy ha nem akar ideiglenes fájlt létrehozni, az egyvonalas segítségével megváltoztathatja az ilyen paraméterek sorrendjét:

    find . -type f -and -name "*.ttf" -exec bash -c "mycommand "$@" extra arguments" {} + 

    amely a mycommand {list of ttf files} extra arguments. Ne feledje, hogy meg kell dupláznia a bash speciális karaktereit a -c zászló után.

    Megjegyzések

    • (1) A fentieknek azt a részét, amely valóban megválaszolja a kérdést, mások már megadták. (2) Amit leírsz, az nem a GNU find hibája vagy hiányossága, hanem a POSIX által megadott helyes viselkedés .
    • +1 Végül valaki, aki azt válaszolja, hogy miért nem működnek a további paraméterek

    ! Hiányosságnak tűnik a POSIX-definícióban.

  • Ha ‘ ve GNU find te ‘ valószínűleg megkapta a GNU cp. Ebben az esetben find ... -exec cp --target-directory ~/.fonts {} + megtarthatja a {} -t a végrehajtási karakterlánc végén.
  • Válasz

    find . -type f -perm 0777 -exec chmod 644 {}\;

    hibát kapott find: missing argument to ``-exec".

    Szóköz hozzáadása {} és \ között kijavította:

    find . -type f -perm 0777 -print -exec chmod 644 {} \;

    Megjegyzések

    • A find parancs a kérdéses kérdésben.
    • A kérdésben nem jól értettem, de a probléma ugyanaz ” find: missing argument a -exec ‘ ” címre, Probléma más-2 okból adódhat, válaszoltam, mert ugyanazt a problémamegállapítást láttam.
    • @Kusalananda jó bánat, a noob megoldást nyújtott a bejelentett hibára, amelyet az OP a kérdés címében és törzsében egyaránt megfogalmaz.
    • @bvj A kérdés kifejezetten foglalkozik a + formában a -exec opcióval find. Ez a válasz kijavítja azt a problémát, amely a kérdést feltevő felhasználónak nincs.

    Válasz

    a fejfájás aránya a múltban az exec szintaxissal. A legtöbb nap inkább a szebb bash szintaxist részesítem előnyben:

    for f in `find a/folder b/folder -name "*.[ch]"`; do grep -I foobar $f; done 

    Van néhány korlátja, amikor a fájlokat csoportként akarja kezelni, mivel mindegyiket sorosan értékelik, de a kimenetet máshol is jól csaphatod

    Megjegyzések

    • Bár ez hajlamos működni, lényegesen kevésbé hasznos, mint a pure-find verzió, mert nem tudja helyesen kezelni a névben szóközzel rendelkező fájlokat.
    • Nem, ezt ne tegye. ‘ Ez megszakad, amint a fájlok szóközöket és más „furcsa” karaktereket tartalmaznak. Ez szintén összetettebb és lassabb, mint a find … -exec … \;, tehát ‘ nincs ok arra, hogy ezt akkor is használd, ha tudod, hogy a fájlneveid szelíd.
    • ez hasznos volt a helyzetemben, amikor több logikai sort kellett futtatnom a fájlnevek alapján (például betűket törölni, könyvtárakat készíteni, majd a fájlokat áthelyezni). Az a próbálkozás, hogy egyszerre több dolgot is meg lehessen csinálni exec, túl nagy fejtörést okozott az 5 perc alatt, amelyet erre szántam. A fájlneveim szelídek voltak, és ez megoldotta a problémámat 🙂

    Vélemény, hozzászólás?

    Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük