Er det muligt at bruge 2 kommandoer i -exec del af find kommando?

Jeg har prøvet noget som:

find . -name "*" -exec chgrp -v new_group {} ; chmod -v 770 {} \; 

og jeg får:

find: manglende argument til -exec
chmod: kan ikke få adgang {}: Ingen sådan fil eller katalog
chmod: kan ikke få adgang ;: Ingen sådan fil eller katalog

Kommentarer

  • Bemærk at -name "*" matcher hvert navn, så det er ' en no-op test, der kan fjernes. Også både chmod og chgrp har en -R mulighed for rekursiv operation.

Svar

Hvad angår kommandoen find, kan du også bare tilføje flere -exec kommandoer i træk:

find . -name "*" -exec chgrp -v new_group "{}" \; -exec chmod -v 770 "{}" \; 

Bemærk, at denne kommando er i sin resultat t, svarende til at bruge

chgrp -v ny_group-fil & & chmod -v 770 fil

på hver fil.

Alle find “s parametre såsom -name, -exec, -size og så videre, er faktisk test : find vil fortsætte med at køre dem en efter en, så længe hele kæden indtil videre er vurderet til sand . Så hver på hinanden følgende -exec kommando udføres kun hvis de foregående returnerede sand (dvs. 0 kommandoer udgangsstatus). Men find forstår også logiske operatorer som eller (-o) og ikke (!). Brug derfor en kæde af -exec test uanset af de tidligere resultater, man skal bruge noget som dette:

find . -name "*" \( -exec chgrp -v new_group {} \; -o -true \) -exec chmod -v 770 {} \; 

Kommentarer

  • +1: Ja, det ' er den mest elegante måde at gøre det på. Hvis du kan forklare, hvorfor du bruger '{}' (apostrofer omkring seler), kan du besøge: unix.stackexchange.com/q/ 8647/4485
  • @user Desværre ved jeg ikke ' om det stadig er nødvendigt. Jeg lavede nogle test lige nu og har ikke ' ikke stødt på en situation, hvor det ville ændre noget. Jeg antager, at det ' er bare " god praksis ", der vil dø ud.
  • Citaterne er vigtige for filer med mellemrum i deres navne.
  • @ naught101 Nej, citaterne er muligvis nødvendige i nogle ikke-standardskaller, f.eks. fish og csh, men er bestemt ikke nødvendige i POSIX-lignende skaller (sh, dash, bash, zsh, ksh, yash).

Svar

find . -name "*" -exec sh -c "chgrp -v new_group "$0" ; chmod -v 770 "$0"" {} \; 

Kommentarer

  • @Gilles: Underet ved -c ' s ulige håndtering på $ 0 får mig til at tro, at dette er forkert, hver gang jeg kigger på det, men det er bestemt korrekt.
  • Jeg kan godt lide, at den eksplicitte skal defineres …
  • Dette svar (og Giles ' er en svare) virker som det bedre svar på spørgsmålet givet sh -c.

Svar

Din kommando parses først af skallen i to kommandoer adskilt af en ;, hvilket svarer til en ny linje:

find . -name "*" -exec chgrp -v new_group {} chmod -v 770 {} \; 

Hvis du vil køre en shell-kommando, skal du påberåbe en shell eksplicit med bash -c (eller sh -c hvis du er ligeglad med, at skallen specifikt er bash):

find . -name "*" -exec sh -c "chgrp -v new_group "$0"; chmod -v 770 "$0"" {} \; 

Bemærk brugen af {} argument til skallen; det er nul-argumentet (som normalt er navnet på skallen eller scriptet, men dette betyder ikke noget her), derfor refereret til "$0".

Du kan sende flere filnavne til skallen ad gangen og få skallen til at gentage dem, det “bliver hurtigere. Her sender jeg _ som scriptnavnet og følgende argumenter er filnavne, som for x (en genvej til for x in "$@") gentages over.

find . -name "*" -exec sh -c "for x; do chgrp -v new_group "$x"; chmod -v 770 "$x"; done" _ {} + 

Bemærk at siden bash 4 eller i zsh behøver du slet ikke finde her. I bash skal du køre shopt -s globstar (læg det i din ~/.bashrc) for at aktivere **/ står for en rekursiv biblioteksglob. (I zsh er dette aktiv hele tiden.) Derefter

chgrp -v new_group -- **/*; chmod -v 770 -- **/* 

eller hvis du ønsker, at filerne skal gentages i rækkefølge

for x in **/*; do chgrp -v new_group -- "$x" chmod -v 770 -- "$x" done 

En forskel med find kommandoen er, at skallen ignorerer prikfiler (filer hvis navn begynder med en . For at inkludere dem skal du først indstille GLOBIGNORE=.:.. i bash; i zsh skal du bruge **/*(D) som globmønsteret.

Kommentarer

  • Dette svar (og Glenn ' s svar) virker som det bedre svar på spørgsmålet givet sh -c.
  • Både chgrp og chmod har en -R mulighed for rekursiv operation.

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *