Vraag Hoe laat ik de opdracht 'cp' een fout niet activeren als het bronbestand niet bestaat?


Ik gebruik Mac OS X. Ik probeer sommige bestanden met een cp-opdracht te kopiëren voor een build-script zoals dit.

cp ./src/*/*.h ./aaa

Maar deze opdracht geeft een foutmelding als er geen .h-bestand in de map ./src staat. Hoe maak je de opdracht om de fout niet op te lossen? (stille mislukking) De fout maakt het bouwresultaat mislukt, maar ik wil alleen kopiëren als er alleen een headerbestand is.


42
2018-06-23 02:55


oorsprong




antwoorden:


Als je het hebt over de foutmelding, kun je dat onderdrukken door het naar de bit-bucket te sturen:

cp ./src/*/*.h ./aaa 2>/dev/null

Als u de afsluitcode en de foutmelding wilt onderdrukken:

cp ./src/*/*.h ./aaa 2>/dev/null || :

56
2018-06-23 04:07



Het zou leuk zijn om uit te leggen wat : betekent in deze context. - Piotr Dobrogost
@PiotrDobrogost: In Bash en enkele andere shells is de dubbele punt een nul-utility (no-op). Haar gespecificeerd door POSIX. Omdat het altijd Waar retourneert, wordt het hier gebruikt om de afsluitcode van een mislukt te onderdrukken cp (moet dat worden gewenst). De schaal is ingebouwd true kan in plaats daarvan worden gebruikt en zou beter leesbaar zijn. - Dennis Williamson
Meer over : - Wat is het doel van de `: '(dubbele punt) GNU Bash ingebouwd? - Piotr Dobrogost
Dit zal ook andere fouten negeren (bron / doelmap bestaat niet, bronbestand bestaat maar is niet leesbaar, schijf vol, alleen-lezen bestandssysteem, IO-fout, cp niet binnen zijn PATH een of andere manier ...) - Vladimir Panteleev


Je bent op zoek naar iets in de trant van

if [ -e file ]
 then cp file /somewhere
fi

(Helaas, de -f optie is niet de droid waar je naar op zoek bent.)

Als u een glob wilt matchen, werkt dat niet; gebruik find in plaats daarvan, bijvoorbeeld:

find ./src -name \*.h -exec cp {} ./destination \;

10
2018-06-23 03:19



Merk op dat er een potentieel TOCTOU-probleem is met een dergelijke benadering (bijvoorbeeld als u dit gebruikt set -een het bestand verdwijnt tussen de [ en de cp aanroepen, zal je script crashen). - Vladimir Panteleev


Oude vraag, maar kan nog steeds relevant zijn voor anderen.
Als je dat niet doet nodig hebben om cp te gebruiken, zou je het met rsync kunnen proberen.
Ga als volgt te werk om alle bestanden van een bron naar een doelmap te kopiëren:

rsync -avzh --ignore-errors /path/to/source /path/to/destination

Rsync wordt geleverd met de meeste Unix-achtige systemen zoals Linux, Mac OS X of FreeBSD.


7
2017-08-22 16:22



Je zou rsync kunnen gebruiken in plaats van cp, door de parameter toe te voegen --ignore-missing-args: rsync -av --ignore-missing-args ./src/*/*.h ./aaa Dit heeft het voordeel ten opzichte van --ignore-errors dat de enige fouten die worden genegeerd, zijn die gerelateerd aan bronbestanden die niet bestaan. Met --ignore-errors elke fout wordt genegeerd, wat gevaarlijk kan zijn. Houd er ook rekening mee dat deze parameter redelijk recent is, dus mogelijk is deze niet aanwezig in oude versies van rsync. - jesjimher


Het resultaat piping naar true zorgt ervoor dat de opdracht altijd zal slagen. Ik heb dit geprobeerd op Linux, maar niet op een Mac OS:

cp ./src/*/*.h ./aaa | true

5
2018-02-06 16:41



De simpele pijp | wordt altijd uitgevoerd terwijl || wordt alleen gedaan in het geval van een fout. En true is meestal een binair getal terwijl de dubbele punt : is een ingebouwde en verbruikt geen PID. - ott--
Een bash-script op MacOS - Yosemite met de opdracht "cp ./src/*/*.h ./aaa" geeft geen foutmelding als de .h-bestanden niet bestaan. - Vivek


U kunt de juiste foutstatus forceren. Met een functie:

$ cpalways () { cp $1 $2 2>/dev/null ; return 0 ; }

Gezien het volgende:

$ ls foo bar baz
ls: baz: No such file or directory
bar foo

Normale kopie retourneert een foutmelding. Het geeft een exitstatus van 1 terug.

$ cp baz bar ; echo $?
cp: baz: No such file or directory
1

Als we de functie cpalways () hierboven gebruiken, worden eventuele fouten verborgen:

$ cpalways baz bar ; echo $?
0
$ cpalways foo bar ; echo $?
0
$ cpalways baz bar ; echo $?
0

1
2018-06-23 04:12