Como verificar o progresso da execução do cp?

54

É possível verificar o andamento da execução do processo cp? Alguns processos respondem a vários sinais KILL para que você possa verificar qual é o status deles. Eu sei que posso executar o cp com o parâmetro -v, mas e se se esquecesse disso, o cp está em execução há muito tempo e quero saber qual arquivo está sendo copiado ou quantos já foram copiados.

Petr
fonte
A maioria das soluções (no Linux e provavelmente em outro POSIX, como o Mac OS X) fica fora do controle quando as operações de leitura são muito mais rápidas que as operações de gravação, exibindo 100% antes da conclusão. O motivo é que as operações de gravação ficam no cache do sistema de arquivos antes de serem realmente executadas. Nesse ponto, as coisas são difíceis de rastrear. Esse truque pode reduzir a diferença: em outro terminal while sleep 1 ; do sync ; done.
Stéphane Gourichon 26/03

Respostas:

31

Sim, executando stat no arquivo de destino e no arquivo local e obtenha um tamanho de arquivo,

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

E você obtém a porcentagem de dados copiados comparando os dois valores, é isso

Em uma implementação muito básica, será assim:

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
}
margarida
fonte
4
não pretende postar uma duplicata da sua sugestão, então adicionei o código aqui. Espero que você não se importe.
Manatwork
@manatwork ah, obrigado, eu estava apenas sendo preguiçoso em dar um exemplo completo :-)
daisy
Excelente, isso está acontecendo na minha caixa de ferramentas em todos os servidores! Obrigado!
ACK_stoverflow
no linux 4, copiando de um drive usb rápido para um micro sd barato em um leitor de cartão antigo, um arquivo de 500mb: cp e sync trava por várias dezenas de minutos. mas se eu declarar o arquivo de origem e destino, recebo exatamente o mesmo número nos dois 10s após o início do cp.
Gcb
40

Nas versões recentes do Mac OS X, basta clicar em CTRL+ Tpara ver o progresso. Na página do manual OSX 10.6 para 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."

Bater CTRL+ Té equivalente a sinalizar o processo atual com o SIGINFO em máquinas BSD-ish, incluindo OSX.

Isso funciona para o dd (1) também.

Eu não acho que o Linux tenha esse mecanismo SIGINFO, e não vejo nada na página de manual do GNU do cp (1) sobre sinais que podem ser usados ​​para relatar o progresso.

erco
fonte
11
Uau! Não me dá muita informação, mas basta saber que estou mvvivo. Obrigado!
Dan Rosenstark
Ele informa apenas a porcentagem concluída para o arquivo individual que ele está copiando quando recebe o sinal. Não fornece a porcentagem concluída de todo o trabalho que está realizando.
Joe C
21

Quando você está copiando muitos arquivos du -s /path/to/destinationou find /path/to/destination | wc -ldá uma idéia de quanto já foi feito.

Você pode descobrir para qual arquivo está sendo copiado lsof -p1234onde 1234 é o ID do processo cp. Em muitos sistemas, pgrep -x cprelata os IDs de todos os processos em execução nomeados cp. Isso pode não ser muito útil, pois a ordem na qual os arquivos em um determinado diretório são copiados é essencialmente imprevisível (em um diretório grande no Linux, ls --sort=noneserá informado ; com uma árvore de diretórios, tente find).

lsof -p1234também informa quantos bytes cpjá foram lidos e gravados para o arquivo atual, na OFFSETcoluna

No Linux, há estatísticas de uso de E / S em /proc/$pid/io(novamente, use o PID do cpprocesso para $pidf). O rcharvalor é o número total de bytes que o processo leu e wcharé o número de bytes que o processo gravou. Isso inclui não apenas dados nos arquivos, mas também metadados nos diretórios. Você pode comparar essa figura com a figura aproximada obtida com du /path/to/source(que conta apenas os dados do arquivo). read_bytese write_bytesinclua apenas o que foi lido ou gravado no armazenamento, ou seja, ele exclui os diagnósticos e os dados do terminal que já estão no cache ou ainda nos buffers.

Gilles 'SO- parar de ser mau'
fonte
4
em tempo real:watch lsof -p1234
mchid
3
Ou tudo de uma só vez:watch lsof -p`pgrep -x cp`
Mike
15

Uma ferramenta relativamente nova que faz exatamente isso é progresso (anteriormente cv [coreutils viewer]).

O que é isso?

Essa ferramenta pode ser descrita como um comando C Minúsculo, Sujo, Somente Linux e OSX que procura comandos básicos do coreutils (cp, mv, dd, tar, gzip / gunzip, cat etc.) atualmente em execução no sistema e exibe a porcentagem de dados copiados.

Como funciona?

Ele simplesmente procura /procpor comandos interessantes e, em seguida, procura nos diretórios fde fdinfoencontra os arquivos abertos, procura posições e reporta o status do maior arquivo.

Amr Mostafa
fonte
5
Este utilitário agora é chamado de progresso: github.com/Xfennec/progress
Taavi Ilves
14

Um dos meus truques favoritos para isso (no Linux) é descobrir o PID do cpprocesso (usando ps | grep cpou similar) e depois procurar /proc/$PID/fd/e /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

Isso mostrará quais arquivos o processo abriu. Se você deseja ver a que distância do arquivo está o processo ...

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

o posparâmetro é a posição do ponteiro de leitura (ou gravação), em bytes.

Jander
fonte
7

Há algumas coisas que você pode fazer. Você pode anexá strace-lo para ver o que está fazendo (a saída pode ser abundante!):

strace -p [pid de cp]

ou você pode lsofdizer quais arquivos ele abriu no momento:

lsof -p [pid de cp]

Se você estiver executando uma grande recursiva cp, poderá pwdxobter o diretório de trabalho atual, o que pode lhe dar uma idéia de como está:

pwdx [pid do cp]
Flup
fonte
4

Embora o OP tenha mencionado especificamente a capacidade de ver como o comando "cp" está progredindo, é preciso dizer que outros utilitários são melhores para esse problema em particular.

Por exemplo:

rsync -avP FROM TO

mostrará o progresso da cópia do arquivo / pasta FROM para o arquivo TO / FOLDER.


# 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

E o rsync lhe dirá quanto é copiado (e a taxa de transferência) ao longo do caminho. Ele funciona para arquivos ou pastas únicos na mesma máquina ou na rede.

Gordon McCrae
fonte
2
Você está respondendo a pergunta errada. A pergunta que você está procurando é: unix.stackexchange.com/questions/2577/… , que já possui uma resposta mencionando rsync.
Muru
1

O que você pode fazer é verificar os arquivos no destino.

Se seus comandos cp forem algo como cp -a <my_source> <my_dest_folder>eu verificaria quais arquivos já foram copiados <my_dest_folder>e cada tamanho de arquivo, para que eu possa ver o progresso. Se <my_source>for um pouco complexo (várias camadas de diretórios), um pequeno script poderá verificar o status. Embora esse script possa consumir um pouco de E / S que não seria usado pelo cpprocesso.

Huygens
fonte
1

Essa ferramenta é um comando do utilitário Linux que procura os comandos básicos do coreutils (cp, mv, dd, tar, gzip / gunzip, cat etc.) atualmente em execução no sistema e exibe a porcentagem de dados copiados:

https://github.com/Xfennec/cv

saidi
fonte
1

Gostaria de acrescentar cpvum pequeno invólucro para o pvque escrevi que imita o uso de cp.

Simples e útil

insira a descrição da imagem aqui

Você pode obtê-lo aqui

nachoparker
fonte
0

Você também pode usar o pipeviewer .

for f in *; do
  pv $f > destination/$f
done
user77376
fonte
0

Use pv -d:

-d PID[:FD], --watchfd PID[:FD]
Em vez de transferir dados, observe o descritor FDde arquivo do processo PIDe mostre seu progresso. […] Se apenas um PIDfor especificado, esse processo será monitorado e todos os arquivos e dispositivos de bloco regulares que ele abrir serão mostrados com uma barra de progresso. O pvprocesso será encerrado quando o processo terminar PID.

( fonte )

Descubra o PID da sua execução cp( pidof cp), digamos que seja 12345; então simplesmente

pv -d 12345

Notas:

  • Execute pvcomo o mesmo usuário que executa cp(ou como root).
  • Como copiar significa ler um arquivo e gravar no outro, espere ver dois arquivos sendo monitorados por vez.
  • Se cpestiver processando arquivos pequenos no momento, provavelmente você não os verá na saída (um arquivo pequeno pode ser fechado muito rápido para pvbuscá-lo). No entanto, alguns aparecerão, e mesmo assim você será capaz de dizer o que cpfaz.
  • pv -d "$(pidof cp)"pode funcionar; mas se houver mais de uma cpexecução, não funcionará. Existe o pidof -sque retorna no máximo um PID, mas você não pode ter certeza de que ele pertencerá ao cpprocesso correto , se houver muitos.
Kamil Maciorowski
fonte
-1

Você pode enviar um sinal para o processo:

kill -SIGUSR1 pid

É ainda mais útil criar um script que pesquise até você pressionar Ctrl-C ou o processo terminar:

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

Trabalhos para dd. Não funciona para cp . Talvez você precise usar outro sinal. Uma vez tentei o SIGINFO, mas ele parece não existir mais na plataforma Intel.

JPT
fonte