Wie überprüfe ich den Fortschritt der Ausführung von cp?

54

Ist es möglich, den Fortschritt der Ausführung des CP-Prozesses zu überprüfen? Einige Prozesse reagieren auf verschiedene KILL-Signale, sodass Sie ihren Status überprüfen können. Ich weiß, dass ich cp mit dem Parameter -v ausführen kann, aber wenn ich das vergesse, läuft cp sehr lange und ich möchte wissen, welche Datei kopiert wird oder wie viele bereits kopiert wurden.

Petr
quelle
Die meisten Lösungen (unter Linux und wahrscheinlich auch unter anderen POSIX-Betriebssystemen wie Mac OS X) geraten aus der Spur, wenn Lesevorgänge viel schneller sind als Schreibvorgänge, und werden 100% vor dem tatsächlichen Abschluss angezeigt. Der Grund dafür ist, dass sich Schreibvorgänge im Dateisystem-Cache befinden, bevor sie tatsächlich ausgeführt werden. Zu diesem Zeitpunkt sind die Dinge schwer zu verfolgen. Dieser Trick kann die Lücke verringern: in einem anderen Terminal while sleep 1 ; do sync ; done.
Stéphane Gourichon

Antworten:

31

Ja, indem Sie stat für die Zieldatei und die lokale Datei ausführen und eine Dateigröße erhalten,

dh stat -c "%s" /bin/ls

Und Sie erhalten den Prozentsatz der kopierten Daten, indem Sie die beiden Werte vergleichen

In einer sehr einfachen Implementierung sieht das so aus:

function cpstat()
{
  local pid="${1:-$(pgrep -xn cp)}" src dst
  [[ "$pid" ]] || return
  while [[ -f "/proc/$pid/fd/3" ]]; do
    read src dst < <(stat -L --printf '%s ' "/proc/$pid/fd/"{3,4})
    (( src )) || break
    printf 'cp %d%%\r' $((dst*100/src))
    sleep 1
  done
  echo
}
Gänseblümchen
quelle
4
Ich beabsichtige nicht, ein Duplikat Ihres Vorschlags zu veröffentlichen. Deshalb habe ich den Code hier hinzugefügt. Hoffe es macht dir nichts aus.
Manatwork
@ Manatwork ah danke, ich war nur faul in der Angabe eines vollständigen Beispiels :-)
Daisy
Hervorragend, das geht in meiner Toolbox auf allen Servern! Vielen Dank!
ACK_stoverflow
Unter Linux 4 hängt die Synchronisierung von einer schnellen USB-Festplatte zu einer billigen Micro-SD-Karte auf einem alten Kartenleser mehrere Dutzend Minuten. aber wenn ich die Quell- und Zieldatei angabe, erhalte ich auf beiden 10ern nach dem Start von cp genau die gleiche Nummer.
GCB
40

In neueren Versionen von Mac OS X können Sie einfach CTRL+ drücken T, um den Fortschritt zu sehen. Aus der OSX 10.6-Manpage für cp (1) :

 "If cp receives a SIGINFO (see the status argument for stty(1)) signal,
 the current input and output file and the percentage complete will be
 written to the standard output."

Das Drücken von CTRL+ Tentspricht dem Signalisieren des aktuellen Prozesses mit SIGINFO auf BSD-basierten Maschinen, einschließlich OSX.

Dies funktioniert auch für dd (1) .

Ich glaube nicht, dass Linux über diesen SIGINFO-Mechanismus verfügt, und in der GNU-Manpage für cp (1) finden Sie keine Informationen zu Signalen, mit denen der Fortschritt gemeldet werden kann.

erco
quelle
1
Beeindruckend! Es gibt mir nicht viele Informationen, aber es ist genug zu wissen, dass ich mvam Leben bin . Vielen Dank!
Dan Rosenstark
Es wird nur der Prozentsatz der vollständigen Dateien angezeigt, die beim Empfang des Signals kopiert werden. Es wird nicht der Prozentsatz angegeben, der für die gesamte auszuführende Arbeit erforderlich ist.
Joe C
21

Wenn Sie viele Dateien kopieren du -s /path/to/destinationoder find /path/to/destination | wc -leine Vorstellung davon haben, wie viel bereits getan wurde.

Sie können herausfinden, welche Datei kopiert wird, lsof -p1234wobei 1234 die Prozess-ID von ist cp. Meldet unter vielen Systemen pgrep -x cpdie Prozess-IDs aller ausgeführten Prozesse mit dem Namen cp. Dies ist möglicherweise nicht sehr nützlich, da die Reihenfolge, in der die Dateien in einem bestimmten Verzeichnis kopiert werden, im Wesentlichen unvorhersehbar ist (in einem großen Verzeichnis unter Linux ls --sort=nonewird dies angezeigt ; versuchen Sie es mit einem Verzeichnisbaum find).

lsof -p1234gibt außerdem an, wie viele Bytes cpfür die aktuelle Datei bereits in der OFFSETSpalte gelesen und geschrieben wurden .

Unter Linux gibt es IO-Nutzungsstatistiken in /proc/$pid/io(verwenden Sie wieder die PID des cpProzesses für $pidf). Der rcharWert ist die Gesamtzahl der Bytes, die der Prozess gelesen hat, und wchardie Anzahl der Bytes, die der Prozess geschrieben hat. Dies umfasst nicht nur Daten in Dateien, sondern auch Metadaten in Verzeichnissen. Sie können diese Zahl mit der ungefähren Zahl vergleichen, die mit du /path/to/source(die nur Dateidaten zählt) erhalten wird. read_bytesund write_bytesnur das einschließen, was aus dem Speicher gelesen oder geschrieben wurde, dh Terminaldiagnose und Daten, die sich bereits im Cache oder noch in Puffern befinden, werden ausgeschlossen.

Gilles 'SO - hör auf böse zu sein'
quelle
4
für Echtzeit:watch lsof -p1234
mchid
3
Oder alles auf einen Streich:watch lsof -p`pgrep -x cp`
Mike
15

Ein relativ neues Tool, das genau das macht, ist progress (ehemals cv [coreutils viewer]).

Was ist es?

Dieses Tool kann als Tiny, Dirty, Linux- und OSX-Only-C-Befehl beschrieben werden, der nach Coreutils-Basisbefehlen (cp, mv, dd, tar, gzip / gunzip, cat usw.) sucht, die derzeit auf Ihrem System ausgeführt werden Zeigt den Prozentsatz der kopierten Daten an.

Wie funktioniert es?

Es /procsucht einfach nach interessanten Befehlen, durchsucht dann Verzeichnisse fdund sucht fdinfonach geöffneten Dateien und Positionen und meldet den Status der größten Datei.

Amr Mostafa
quelle
5
Dieses Dienstprogramm heißt jetzt progress: github.com/Xfennec/progress
Taavi Ilves
14

Einer meiner Lieblingstricks (unter Linux) ist es, die PID des cpProzesses herauszufinden (mithilfe von ps | grep cpoder ähnlichem) und dann in /proc/$PID/fd/und zu suchen /proc/$PID/fdinfo/.

$ cp -r y z
^Z
$ ls -l /proc/8614/fd
lrwx------ 1 jander jander 64 Aug  2 15:21 0 -> /dev/pts/4
lrwx------ 1 jander jander 64 Aug  2 15:21 1 -> /dev/pts/4
lrwx------ 1 jander jander 64 Aug  2 15:20 2 -> /dev/pts/4
lr-x------ 1 jander jander 64 Aug  2 15:21 3 -> /home/jander/y/foo.tgz
l-wx------ 1 jander jander 64 Aug  2 15:21 4 -> /home/jander/z/foo.tgz

Dies zeigt Ihnen, welche Dateien der Prozess geöffnet hat. Wenn Sie sehen möchten, wie weit der Prozess in der Datei ist ...

$ cat /proc/8614/fdinfo/3
pos:    105381888
flags:  0500000

Der posParameter ist die Position des Lese- (oder Schreib-) Zeigers in Byte.

Jander
quelle
7

Sie können einige Dinge tun. Sie können es anhängen, straceum zu sehen, was es tut (die Ausgabe kann reichlich sein!):

strace -p [pid von cp]

oder Sie könnten Ihnen lsofsagen, welche Dateien gerade geöffnet sind:

lsof -p [pid von cp]

Wenn Sie eine große rekursive Methode ausführen cp, können Sie pwdxdas aktuelle Arbeitsverzeichnis abrufen, um eine Vorstellung davon zu erhalten, wie es funktioniert:

pwdx [pid von cp]
Flup
quelle
4

Während das OP speziell die Möglichkeit erwähnt hat, den Fortschritt des "cp" -Befehls zu verfolgen, muss gesagt werden, dass andere Dienstprogramme für dieses spezielle Problem besser geeignet sind.

Zum Beispiel:

rsync -avP FROM TO

zeigt den Fortschritt des Kopierens der FROM-Datei / des Ordners in die TO-Datei / den FOLDER an.


# rsync -avP Video.mp4  /run/media/user1/3.8G/

sending incremental file list
Video.mp4
    565,170,046 100%   51.23MB/s    0:00:10 (xfr#1, to-chk=0/1)

sent 565,308,115 bytes  received 134 bytes  5,210,214.28 bytes/sec
total size is 565,170,046  speedup is 1.00

Und rsync teilt Ihnen mit, wie viel kopiert wurde (und mit welcher Übertragungsrate). Es funktioniert für einzelne Dateien oder Ordner auf demselben Computer oder über das Netzwerk.

Gordon McCrae
quelle
2
Sie beantworten die falsche Frage. Die Frage, die Sie suchen, lautet: unix.stackexchange.com/questions/2577/… , auf die bereits eine Antwort vorhanden ist rsync.
muru
1

Sie können die Dateien am Zielort überprüfen.

Wenn Ihr cp-Befehl so ähnlich ist, cp -a <my_source> <my_dest_folder>würde ich prüfen, welche Dateien bereits kopiert wurden <my_dest_folder>und in welcher Dateigröße, damit ich den Fortschritt sehen kann. Wenn das <my_source>etwas komplex ist (mehrere Verzeichnisebenen), kann ein kleines Skript den Status überprüfen. Obwohl ein solches Skript ein wenig E / A verbrauchen könnte, würde es dann nicht vom cpProzess verwendet.

Huygens
quelle
1

Bei diesem Tool handelt es sich um ein Linux-Dienstprogramm, das nach Coreutils-Grundbefehlen sucht (cp, mv, dd, tar, gzip / gunzip, cat usw.), die derzeit auf Ihrem System ausgeführt werden, und den Prozentsatz der kopierten Daten anzeigt:

https://github.com/Xfennec/cv

saidi
quelle
1

Ich möchte hinzufügen cpv, ein kleiner Wrapper für das pv, was ich geschrieben habe, der die Verwendung von imitiert cp.

Einfach und nützlich

Bildbeschreibung hier eingeben

Sie können es hier bekommen

nachoparker
quelle
0

Verwendung pv -d:

-d PID[:FD], --watchfd PID[:FD]
Anstatt Daten zu übertragen, beobachten Sie den Dateideskriptor FDdes Prozesses PIDund zeigen Sie dessen Fortschritt an. […] Wenn nur a PIDangegeben wird, wird dieser Prozess überwacht und alle regulären Dateien und Blockgeräte, die geöffnet werden, werden mit einem Fortschrittsbalken angezeigt. Der pvProzess wird beendet, wenn der Prozess beendet wird PID.

( Quelle )

Finden Sie die PID Ihres running cp( pidof cp) heraus, sagen wir, es ist 12345; dann einfach

pv -d 12345

Anmerkungen:

  • Führen Sie pvdas Programm als derselbe Benutzer aus, der es ausführt cp(oder als root).
  • Da beim Kopieren eine Datei gelesen und in die andere geschrieben werden muss, müssen Sie damit rechnen, dass zwei Dateien gleichzeitig überwacht werden.
  • Wenn cpgerade kleine Dateien verarbeitet werden, werden wahrscheinlich nicht alle in der Ausgabe angezeigt (eine kleine Datei wird möglicherweise zu schnell geschlossen pv, um sie abholen zu können). Dennoch werden einige auftauchen, so dass Sie selbst dann in der Lage sein werden, zu sagen, was cptut.
  • pv -d "$(pidof cp)"könnte funktionieren; aber wenn es mehr als ein cplaufendes gibt, arbeitet es nicht. Es pidof -sgibt höchstens eine PID, aber Sie können nicht sicher sein, ob sie zum richtigen cpProzess gehört, wenn es viele gibt.
Kamil Maciorowski
quelle
-1

Sie können ein Signal an den Prozess senden:

kill -SIGUSR1 pid

Es ist noch nützlicher, ein Skript zu erstellen, das so lange abruft, bis Sie Strg-C drücken oder der Vorgang abgeschlossen ist:

while [ : ] ; do kill -SIGUSR1 $1 && sleep 1m || exit ; done

Funktioniert für dd. Funktioniert nicht für CP . Möglicherweise müssen Sie ein anderes Signal verwenden. Ich habe SIGINFO einmal ausprobiert, aber es scheint auf der Intel-Plattform nicht mehr zu existieren.

JPT
quelle