Frage Wie kann der Befehl 'cp' keinen Fehler auslösen, wenn die Quelldatei nicht existiert?


Ich benutze Mac OS X. Ich versuche, einige Dateien mit cp-Befehl für ein Build-Skript wie folgt zu kopieren.

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

Dieser Befehl löst jedoch einen Fehler aus, wenn sich keine .h-Datei im Verzeichnis ./src befindet. Wie kann der Befehl den Fehler nicht auslösen? (Silent failure) Der Fehler lässt das Build-Ergebnis scheitern, aber ich möchte nur kopieren, wenn nur eine Header-Datei vorhanden ist.


42
2018-06-23 02:55


Ursprung




Antworten:


Wenn Sie über die Fehlermeldung sprechen, können Sie dies unterdrücken, indem Sie sie an den Bit-Bucket senden:

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

Wenn Sie den Exit-Code und die Fehlermeldung unterdrücken möchten:

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

56
2018-06-23 04:07



Es wäre schön, was zu erklären : bedeutet in diesem Zusammenhang. - Piotr Dobrogost
@PiotrDobrogost: In Bash und einigen anderen Shells ist der Doppelpunkt ein Null-Dienstprogramm (no-op). Es ist spezifizierten durch POSIX. Da es immer true zurückgibt, wird es hier verwendet, um den Exit-Code eines fehlgeschlagenen Codes zu unterdrücken cp (sollte das gewünscht sein). Die eingebaute Muschel true könnte stattdessen verwendet werden und wäre besser lesbar. - Dennis Williamson
Mehr über : - Was ist der Zweck der `: '(Doppelpunkt) GNU Bash Builttin? - Piotr Dobrogost
Dies ignoriert auch andere Fehler (Quell- / Zielverzeichnis existiert nicht, Quelldatei existiert, ist aber nicht lesbar, Platte voll, Nur-Lese-Dateisystem, IO-Fehler, cp nicht sein PATH irgendwie...) - Vladimir Panteleev


Sie suchen nach etwas in der Art von

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

(Leider, die -f Option ist nicht der Droide, den du suchst.)

Wenn Sie einen Glob passen möchten, wird das nicht funktionieren; benutzen find stattdessen z.B .:

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

10
2018-06-23 03:19



Beachten Sie, dass bei einem solchen Ansatz ein potenzielles TOCTOU-Problem auftritt (z. B. wenn Sie set -e, und die Datei verschwindet zwischen den [ und das cp Aufrufe, Ihr Skript wird abstürzen). - Vladimir Panteleev


Alte Frage, könnte aber für andere noch relevant sein.
Wenn du es nicht tust brauchen Um cp zu verwenden, könnten Sie mit rsync versuchen.
Führen Sie Folgendes aus, um alle Dateien von einer Quelle in ein Zielverzeichnis zu kopieren:

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

Rsync kommt mit den meisten Unix-ähnlichen Systemen wie Linux, Mac OS X oder FreeBSD.


7
2017-08-22 16:22



Sie könnten rsync anstelle von cp verwenden und den Parameter hinzufügen --ignore-missing-args: rsync -av --ignore-missing-args ./src/*/*.h ./aaa Dies hat den Vorteil gegenüber --ignore-errors dass die einzigen ignorierten Fehler diejenigen sind, die sich auf Quelldateien beziehen, die nicht existieren. Mit --ignore-errors Jeder Fehler wird ignoriert, was gefährlich sein kann. Berücksichtigen Sie auch, dass dieser Parameter relativ neu ist, sodass er in alten Versionen von rsync möglicherweise nicht vorhanden ist. - jesjimher


Wenn das Ergebnis auf "true" gestellt wird, ist sichergestellt, dass der Befehl immer erfolgreich ist. Ich habe das unter Linux versucht, aber nicht unter Mac OS:

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

5
2018-02-06 16:41



Das einfache Rohr | läuft immer während || erfolgt nur im Fehlerfall. Und true ist normalerweise eine binäre, während der Doppelpunkt : ist ein eingebauter und verbraucht keine PID. - ott--
Ein Bash-Skript auf MacOS - Yosemite, das den Befehl "cp ./src/*/*.h ./aaa" enthält, gibt keinen Fehler aus, wenn die .h-Dateien nicht existieren. - Vivek


Sie könnten den korrekten Fehlerstatus erzwingen. Mit einer Funktion:

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

Angesichts der folgenden:

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

Regelmäßige Kopie wird einen Fehler zurückgeben. Es wird einen Exit-Status von 1 zurückgeben.

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

Wenn wir die Funktion cpalways () oben verwenden, werden alle Fehler ausgeblendet:

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

1
2018-06-23 04:12