Bagaimana cara memeriksa kemajuan menjalankan cp?

54

Apakah mungkin untuk memeriksa progres menjalankan proses cp? Beberapa proses merespons berbagai sinyal KILL sehingga Anda dapat memeriksa statusnya. Saya tahu bahwa saya dapat menjalankan cp dengan parameter -v tetapi bagaimana jika lupa melakukan itu, cp berjalan untuk waktu yang sangat lama dan saya ingin tahu file mana yang sedang disalin, atau berapa banyak yang sudah disalin.

Petr
sumber
Sebagian besar solusi (di Linux dan mungkin POSIX lainnya, seperti Mac OS X) keluar jalur ketika operasi baca jauh lebih cepat daripada operasi tulis, menampilkan 100% jauh sebelum penyelesaian yang sebenarnya. Alasannya adalah operasi tulis duduk di cache sistem file sebelum mereka benar-benar dilakukan. Pada titik itu, banyak hal yang sulit dilacak. Trik ini dapat mengurangi kesenjangan: di terminal lain while sleep 1 ; do sync ; done.
Stéphane Gourichon

Jawaban:

31

Ya, dengan menjalankan stat pada file target dan file lokal, dan mendapatkan ukuran file,

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

Dan Anda mendapatkan persentase data yang disalin dengan membandingkan dua nilai, itu saja

Dalam implementasi yang sangat mendasar akan terlihat seperti ini:

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
}
bunga aster
sumber
4
tidak bermaksud mengirim duplikat saran Anda, jadi saya menambahkan kode di sini. Semoga kamu tidak keberatan.
manatwork
@manatwork ah terima kasih, saya hanya malas memberikan contoh lengkap :-)
daisy
Luar biasa, ini ada di kotak alat saya di semua server! Terima kasih!
ACK_stoverflow
di linux 4, cp'ing dari satu usb drive cepat ke micro sd murah pada pembaca kartu lama file 500mb: cp dan sinkronisasi hang selama beberapa lusin menit. tetapi jika saya stat file sumber dan tujuan saya mendapatkan nomor yang sama persis pada kedua 10s setelah cp dimulai.
gcb
40

Pada versi terbaru Mac OS X Anda dapat menekan CTRL+ Tuntuk melihat perkembangannya. Dari halaman manual OSX 10.6 untuk 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."

Memukul CTRL+ Tsama dengan menandakan proses saat ini dengan SIGINFO pada mesin BSD-ish, termasuk OSX.

Ini berfungsi untuk dd (1) juga.

Saya tidak berpikir Linux memiliki mekanisme SIGINFO ini, dan tidak melihat apa pun di halaman manual GNU untuk cp (1) tentang sinyal yang dapat digunakan untuk melaporkan kemajuan.

erco
sumber
1
Wow! Itu tidak memberi saya banyak informasi, tetapi cukup untuk mengetahui bahwa saya mvmasih hidup. Terima kasih!
Dan Rosenstark
Ini hanya memberitahu Anda persen lengkap untuk file individual yang disalin ketika menerima sinyal. Itu tidak memberikan persen selesai dari seluruh pekerjaan yang dilakukannya.
Joe C
21

Saat Anda menyalin banyak file, du -s /path/to/destinationatau find /path/to/destination | wc -lmemberi Anda gambaran tentang berapa banyak yang telah dilakukan.

Anda dapat mengetahui file mana yang sedang disalin di lsof -p1234mana 1234 adalah ID proses cp. Di bawah banyak sistem, pgrep -x cpmelaporkan ID proses dari semua proses yang berjalan yang dinamai cp. Ini mungkin tidak terlalu berguna karena urutan di mana file di dalam direktori yang diberikan disalin pada dasarnya tidak dapat diprediksi (dalam direktori besar di Linux, ls --sort=noneakan memberitahu Anda; dengan pohon direktori, coba find).

lsof -p1234juga memberi tahu Anda berapa banyak byte yang cpsudah membaca dan menulis untuk file saat ini, di OFFSETkolom.

Di Linux, ada statistik penggunaan IO di /proc/$pid/io(sekali lagi, gunakan PID cpproses untuk $pidf). The rcharnilai adalah jumlah total byte bahwa proses telah membaca, dan wcharadalah jumlah byte bahwa proses telah menulis. Ini tidak hanya mencakup data dalam file tetapi juga metadata dalam direktori. Anda dapat membandingkan angka itu dengan angka perkiraan yang diperoleh du /path/to/source(yang hanya menghitung data file). read_bytesdan write_byteshanya menyertakan apa yang telah dibaca atau ditulis dari penyimpanan, yaitu tidak termasuk diagnostik terminal dan data yang sudah ada dalam cache atau masih dalam buffer.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
4
untuk waktu nyata:watch lsof -p1234
mchid
3
Atau semuanya:watch lsof -p`pgrep -x cp`
Mike
15

Alat yang relatif baru yang melakukan persis itu adalah kemajuan (sebelumnya cv [coreutils viewer]).

Apa itu?

Alat ini dapat digambarkan sebagai perintah C Tiny, Dirty, Linux-and-OSX-Only yang mencari perintah dasar coreutils (cp, mv, dd, tar, gzip / gunzip, cat, dll.) Saat ini berjalan pada sistem Anda dan menampilkan persentase data yang disalin.

Bagaimana cara kerjanya?

Ini hanya memindai /procperintah yang menarik, dan kemudian melihat direktori fddan fdinfomenemukan file yang dibuka dan mencari posisi, dan melaporkan status untuk file terbesar.

Amr Mostafa
sumber
5
Utilitas ini sekarang disebut progres: github.com/Xfennec/progress
Taavi Ilves
14

Salah satu trik favorit saya untuk ini (di Linux) adalah untuk mengetahui PID dari cpproses (menggunakan ps | grep cpatau serupa), dan kemudian mencari /proc/$PID/fd/dan /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

Ini akan menunjukkan kepada Anda file apa yang prosesnya telah buka. Jika Anda ingin melihat seberapa jauh ke dalam file prosesnya adalah ...

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

yang posparameter adalah posisi membaca (atau menulis) pointer, dalam byte.

Jander
sumber
7

Ada beberapa hal yang bisa Anda lakukan. Anda dapat melampirkannya straceuntuk melihat apa yang dilakukannya (output mungkin berlebihan!):

strace -p [pid of cp]

atau Anda bisa lsofmemberi tahu Anda file mana yang saat ini dibuka:

lsof -p [pid dari cp]

Jika Anda menjalankan rekursif besar cp, Anda bisa menggunakan pwdxuntuk mendapatkan direktori kerja saat ini, yang dapat memberi Anda beberapa ide bagaimana melakukannya:

pwdx [pid dari cp]
Flup
sumber
4

Sementara OP secara khusus menyebutkan kemampuan untuk melihat bagaimana perintah "cp" mengalami kemajuan, harus dikatakan bahwa utilitas lain lebih baik untuk masalah khusus ini.

Sebagai contoh:

rsync -avP FROM TO

akan menunjukkan progres penyalinan file FROM / folder ke file 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

Dan rsync akan memberi tahu Anda berapa yang disalin (dan kecepatan transfer) di sepanjang jalan. Ini berfungsi untuk file atau folder tunggal baik pada mesin yang sama atau di seluruh jaringan.

Gordon McCrae
sumber
2
Anda menjawab pertanyaan yang salah. Pertanyaan yang Anda cari adalah: unix.stackexchange.com/questions/2577/… , yang sudah memiliki jawaban yang menyebutkan rsync.
muru
1

Yang dapat Anda lakukan adalah memeriksa file di tempat tujuan.

Jika perintah cp Anda seperti cp -a <my_source> <my_dest_folder>saya akan memeriksa file mana yang sudah disalin <my_dest_folder>dan masing-masing ukuran file, jadi saya bisa melihat perkembangannya. Jika <my_source>agak rumit (beberapa lapisan direktori) maka skrip kecil akan dapat memeriksa statusnya. Meskipun skrip seperti itu dapat mengkonsumsi sedikit I / O yang kemudian tidak akan digunakan oleh cpproses.

Huygens
sumber
1

Alat ini adalah perintah utilitas Linux yang mencari perintah dasar coreutils (cp, mv, dd, tar, gzip / gunzip, cat, dll.) Yang saat ini berjalan di sistem Anda dan menampilkan persentase data yang disalin:

https://github.com/Xfennec/cv

Saidi
sumber
1

Saya ingin menambahkan cpv, bungkus kecil untuk pvitu saya tulis yang meniru penggunaan cp.

Sederhana dan bermanfaat

masukkan deskripsi gambar di sini

Anda bisa mendapatkannya di sini

nachoparker
sumber
0

Anda juga dapat menggunakan pipeviewer .

for f in *; do
  pv $f > destination/$f
done
pengguna77376
sumber
0

Gunakan pv -d:

-d PID[:FD], --watchfd PID[:FD]
Alih-alih mentransfer data, tonton deskriptor file FDproses PID, dan tunjukkan progresnya. […] Jika hanya PIDditentukan, maka proses itu akan ditonton, dan semua file biasa dan blokir perangkat yang dibuka akan ditampilkan dengan bilah progres. The pvProses akan keluar ketika proses PIDkeluar.

( sumber )

Cari tahu PID dari menjalankan Anda cp( pidof cp), katakanlah itu adalah 12345; maka sederhananya

pv -d 12345

Catatan:

  • Jalankan pvsebagai pengguna yang sama yang menjalankan cp(atau sebagai root).
  • Karena penyalinan berarti membaca satu file dan menulis ke yang lain, berharap untuk melihat dua file dipantau pada suatu waktu.
  • Jika cpsedang memproses file kecil saat ini, Anda mungkin tidak akan melihat semuanya dalam output (file kecil mungkin ditutup terlalu cepat untuk pvdiambil). Namun beberapa akan muncul, sehingga Anda pun dapat mengetahui apa yang cpterjadi.
  • pv -d "$(pidof cp)"dapat bekerja; tetapi jika ada lebih dari satu cpberlari, itu tidak akan berhasil. Ada pidof -syang mengembalikan paling banyak satu PID, tetapi Anda tidak bisa memastikan itu akan menjadi bagian dari cpproses yang benar jika ada banyak.
Kamil Maciorowski
sumber
-1

Anda dapat mengirim sinyal ke proses:

kill -SIGUSR1 pid

Bahkan lebih berguna untuk membuat skrip yang melakukan polling sampai Anda menekan Ctrl-C atau proses selesai:

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

Bekerja untuk dd. Tidak berfungsi untuk cp . Mungkin Anda harus menggunakan sinyal lain. Saya pernah mencoba SIGINFO, tetapi sepertinya tidak ada lagi di platform Intel.

JPT
sumber