Comment vérifier la progression de l'exécution de cp?

54

Est-il possible de vérifier la progression de l'exécution du processus cp? Certains processus répondent à divers signaux KILL afin que vous puissiez vérifier leur statut. Je sais que je peux exécuter cp avec le paramètre -v, mais si j'oublie de le faire, cp fonctionne depuis très longtemps et je veux savoir quel fichier est copié ou combien ont déjà été copiés.

Petr
la source
La plupart des solutions (sous Linux et probablement d'autres POSIX, comme Mac OS X) s'égarent lorsque les opérations de lecture sont beaucoup plus rapides que les opérations d'écriture, affichant 100% bien avant la fin. La raison en est que les opérations d'écriture sont dans le cache du système de fichiers avant d'être réellement effectuées. À ce stade, les choses sont difficiles à suivre. Cette astuce peut réduire l’écart: dans un autre terminal while sleep 1 ; do sync ; done.
Stéphane Gourichon

Réponses:

31

Oui, en exécutant stat sur le fichier cible et le fichier local, et obtenir une taille de fichier,

c'est à dire stat -c "%s" /bin/ls

Et vous obtenez le pourcentage de données copiées en comparant les deux valeurs, c'est tout

Dans une implémentation très basique qui ressemblera à ceci:

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
}
Marguerite
la source
4
pas destiné à poster une copie de votre suggestion, alors j’ai ajouté le code ici. J'espère que ça ne vous dérange pas.
Manatwork
@manatwork ah merci, j'étais juste paresseux pour donner un exemple complet :-)
daisy
Excellent, cela va dans ma boîte à outils sur tous les serveurs! Merci!
ACK_stoverflow
sur linux 4, cp 'd' un lecteur usb rapide à un micro sd bon marché sur un ancien lecteur de carte, un fichier de 500 Mo: cp et sync se bloquent pendant plusieurs dizaines de minutes. mais si je stat le fichier source et destination, je reçois le même nombre exact sur les deux 10 après le démarrage de cp.
GBC
40

Sur les versions récentes de Mac OS X, vous pouvez simplement appuyer sur CTRL+ Tpour voir les progrès. Depuis la page de manuel OSX 10.6 pour 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."

Frapper CTRL+ Téquivaut à signaler le processus en cours avec SIGINFO sur des machines BSD, y compris OSX.

Cela fonctionne aussi pour dd (1) .

Je ne pense pas que Linux ait ce mécanisme SIGINFO et ne voit rien dans la page de manuel GNU de cp (1) concernant les signaux pouvant être utilisés pour rendre compte des progrès.

erco
la source
1
Hou la la! Cela ne me donne pas beaucoup d'informations, mais c'est suffisant pour savoir que ma mvvie est en vie. Merci!
Dan Rosenstark le
Il vous indique uniquement le pourcentage terminé pour le fichier individuel qu'il copie lors de la réception du signal. Cela ne donne pas le pourcentage terminé de tout le travail qu'il fait.
Joe C
21

Lorsque vous copiez beaucoup de fichiers du -s /path/to/destinationou find /path/to/destination | wc -lvous donne une idée de ce qui a déjà été fait.

Vous pouvez trouver le fichier en cours de copie avec lsof -p12341234 l'identifiant de processus de cp. Sous de nombreux systèmes, pgrep -x cpindique les ID de processus de tous les processus en cours nommés cp. Cela peut ne pas être très utile car l'ordre dans lequel les fichiers d'un répertoire donné sont copiés est essentiellement imprévisible (dans un grand répertoire sous Linux, ls --sort=nonevous le saurez; avec une arborescence de répertoires, essayez find).

lsof -p1234vous indique également combien d’octets cpont déjà été lus et écrits pour le fichier en cours, dans la OFFSETcolonne.

Sous Linux, il existe des statistiques d'utilisation d'E / S dans /proc/$pid/io(encore une fois, utilisez le PID du cpprocessus pour $pidf). La rcharvaleur correspond au nombre total d'octets lus par le processus et wcharau nombre d'octets écrits par le processus. Cela inclut non seulement les données dans les fichiers, mais également les métadonnées dans les répertoires. Vous pouvez comparer ce chiffre avec le chiffre approximatif obtenu avec du /path/to/source(qui ne compte que les données du fichier). read_byteset write_bytesn'inclut que ce qui a été lu ou écrit à partir de la mémoire, c'est-à-dire qu'il exclut les diagnostics de terminal et les données déjà en cache ou encore dans les mémoires tampons.

Gilles, arrête de faire le mal
la source
4
pour le temps réel:watch lsof -p1234
mchid
3
Ou tout d'un coup:watch lsof -p`pgrep -x cp`
Mike
15

Un outil relativement nouveau qui fait exactement cela est le progrès (anciennement cv [coreutils viewer]).

Qu'Est-ce que c'est?

Cet outil peut être décrit comme une commande C minuscule, sale, Linux-et-OSX-Only recherchant les commandes de base de coreutils (cp, mv, jj, tar, gzip / gunzip, cat, etc.) en cours d'exécution sur votre système et affiche le pourcentage de données copiées.

Comment ça marche?

Il recherche simplement /procles commandes intéressantes, puis examine les répertoires fd, fdinforecherche les fichiers ouverts, recherche les positions et indique l'état du fichier le plus volumineux.

Amr Mostafa
la source
5
Cette utilité s'appelle maintenant progress: github.com/Xfennec/progress
Taavi Ilves
14

L’un de mes trucs préférés pour cela (sous Linux) est de trouver le PID du cpprocessus (using ps | grep cpou similaire), puis de regarder dedans /proc/$PID/fd/et /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

Cela vous montrera quels fichiers le processus a ouverts. Si vous voulez voir à quelle distance du fichier se trouve le processus ...

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

le posparamètre est la position du pointeur de lecture (ou d'écriture), en octets.

Jander
la source
7

Il y a quelques choses que vous pouvez faire. Vous pouvez y joindre stracepour voir ce qu'il fait (la sortie peut être copieuse!):

strace -p [pid de cp]

ou vous pourriez arriver lsofà vous dire quels fichiers il a actuellement ouvert:

lsof -p [pid de cp]

Si vous exécutez une grosse opération récursive cp, vous pouvez utiliser pwdxle répertoire de travail actuel, ce qui peut vous donner une idée de son fonctionnement:

pwdx [pid de cp]
Flup
la source
4

Bien que le PO ait spécifiquement mentionné la possibilité de voir comment la commande "cp" progresse, il faut dire que d'autres utilitaires sont meilleurs pour ce problème particulier.

Par exemple:

rsync -avP FROM TO

affichera la progression de la copie du fichier / dossier FROM dans le fichier / dossier TO.


# 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

Et rsync vous dira combien il est copié (et le taux de transfert) en cours de route. Cela fonctionne pour des fichiers simples ou des dossiers à la fois sur le même ordinateur ou sur le réseau.

Gordon McCrae
la source
2
Vous répondez à la mauvaise question. La question que vous cherchez est la suivante: unix.stackexchange.com/questions/2577/… , qui contient déjà une réponse rsync.
muru
1

Ce que vous pouvez faire est de vérifier les fichiers à la destination.

Si vos commandes cp ressemblent à quelque chose du genre, cp -a <my_source> <my_dest_folder>je vérifierais quels fichiers sont déjà copiés <my_dest_folder>et quelle est la taille de chaque fichier, afin que je puisse voir la progression. Si le <my_source>est un peu complexe (plusieurs couches de répertoires), alors un petit script pourra vérifier le statut. Bien qu'un tel script puisse consommer un peu d'E / S qui ne serait alors pas utilisé par le cpprocessus.

Huygens
la source
1

Cet outil est une commande utilitaire Linux qui recherche les commandes de base coreutils (cp, mv, jj, tar, gzip / gunzip, cat, etc.) en cours d'exécution sur votre système et affiche le pourcentage de données copiées:

https://github.com/Xfennec/cv

saidi
la source
1

Je voudrais ajouter cpv, un peu de wrapper pour ce pvque j’ai écrit qui imite l’utilisation de cp.

Simple et utile

entrez la description de l'image ici

Vous pouvez l'obtenir ici

nachoparker
la source
0

Vous pouvez également utiliser pipeviewer .

for f in *; do
  pv $f > destination/$f
done
utilisateur77376
la source
0

Utiliser pv -d:

-d PID[:FD], --watchfd PID[:FD]
Au lieu de transférer des données, observez le descripteur FDde fichier du processus PIDet affichez sa progression. […] Si seulement un PIDest spécifié, alors ce processus sera surveillé, et tous les fichiers normaux et les périphériques bloqués qu'il ouvriront seront affichés avec une barre de progression. Le pvprocessus se terminera à la fin du processus PID.

( source )

Découvrez le PID de votre running cp( pidof cp), disons que c'est 12345; alors simplement

pv -d 12345

Remarques:

  • Exécuter en pvtant que même utilisateur que cp(ou en tant que root).
  • Comme copier signifie lire un fichier et écrire dans un autre, attendez-vous à ce que deux fichiers soient surveillés à la fois.
  • Si vous cptraitez actuellement de petits fichiers, vous ne verrez probablement pas tous ceux-ci dans la sortie (un petit fichier peut être fermé trop rapidement pour pvpouvoir le récupérer). Pourtant, certains vont apparaître, vous pourrez donc même savoir ce qui se cppasse.
  • pv -d "$(pidof cp)"peut travailler; mais s'il y a plus d'un en cpcours d'exécution, cela ne fonctionnera pas. Il y en a pidof -squi renvoie au plus un PID, mais vous ne pouvez pas être sûr qu'il appartiendra au bon cpprocessus s'il y en a plusieurs.
Kamil Maciorowski
la source
-1

Vous pouvez envoyer un signal au processus:

kill -SIGUSR1 pid

Il est encore plus utile de créer un script qui interroge jusqu'à ce que vous appuyiez sur Ctrl-C ou que le processus soit terminé:

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

Fonctionne pour dd. Ça ne marche pas pour cp . Peut-être que vous devez utiliser un autre signal. J'ai déjà essayé SIGINFO, mais il ne semble plus exister sur la plate-forme Intel.

JPT
la source