Как проверить ход запуска cp?

54

Можно ли проверить ход выполнения процесса cp? Некоторые процессы реагируют на различные сигналы KILL, чтобы вы могли проверить их состояние. Я знаю, что могу запустить cp с параметром -v, но что, если забыли это сделать, cp работает очень долго, и я хочу знать, какой файл копируется, или сколько уже скопировано.

Petr
источник
Большинство решений (в Linux и, возможно, в других POSIX, таких как Mac OS X) сбиваются с пути, когда операции чтения выполняются намного быстрее, чем операции записи, отображая 100% задолго до фактического завершения. Причина в том, что операции записи находятся в кеше файловой системы до того, как они фактически выполняются. В этот момент все сложно отследить. Этот трюк может уменьшить разрыв: в другом терминале while sleep 1 ; do sync ; done.
Стефан Гурихон

Ответы:

31

Да, запустив stat для целевого файла и локального файла, и получите размер файла,

т.е. stat -c "%s" /bin/ls

И вы получаете процент скопированных данных, сравнивая два значения, вот и все

В очень простой реализации это будет выглядеть так:

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
}
маргаритка
источник
4
не собирался публиковать дубликат вашего предложения, поэтому я добавил код здесь. Надеюсь, ты не возражаешь.
Манатворк
@ manatwork ах, спасибо, я просто ленился привести полный пример :-)
маргаритка
Отлично, это происходит в моем наборе инструментов на всех серверах! Спасибо!
ACK_stoverflow
на Linux 4 cp'ing с одного быстрого USB-накопителя на дешевый micro sd на старом картридере файл 500 Мб: cp и синхронизация зависают на несколько десятков минут. но если я определяю исходный файл и файл назначения, я получаю одинаковое число в течение 10 секунд после запуска cp.
gcb
40

В последних версиях Mac OS X вы можете просто нажать CTRL+, Tчтобы увидеть прогресс. Из справочной страницы OSX 10.6 для 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."

Нажатие CTRL+ Tэквивалентно сигналу текущего процесса с помощью SIGINFO на машинах BSD-ish, включая OSX.

Это работает и для dd (1) .

Я не думаю, что в Linux есть такой механизм SIGINFO, и я не вижу в справочной странице GNU для cp (1) ничего о сигналах, которые можно использовать для сообщения о прогрессе.

ERCO
источник
1
Вау! Это не дает мне много информации, но достаточно знать, что мой mvжив. Спасибо!
Дэн Розенстарк
Он только сообщает вам процент завершения для отдельного файла, который он копирует, когда получает сигнал. Это не дает процент выполнения всей работы, которую он выполняет.
Джо С
21

Когда вы копируете много файлов du -s /path/to/destinationили find /path/to/destination | wc -lдаете представление о том, сколько уже сделано.

Вы можете узнать, в какой файл копируется, lsof -p1234где 1234 - это идентификатор процесса cp. Во многих системах pgrep -x cpсообщает идентификаторы всех запущенных процессов cp. Это может быть не очень полезно, так как порядок, в котором копируются файлы внутри данного каталога, по сути непредсказуем (в большом каталоге в Linux ls --sort=noneвам скажут; с деревом каталогов, попробуйте find).

lsof -p1234также сообщает вам, сколько байтов cpуже прочитано и записано для текущего файла в OFFSETстолбце.

В Linux есть статистика использования IO /proc/$pid/io(опять же, используйте PID cpпроцесса для $pidf). rcharЗначение представляет собой общее количество байт , что процесс чтения и wcharэто количество байт , что процесс записи. Это включает в себя не только данные в файлах, но и метаданные в каталогах. Вы можете сравнить эту цифру с приблизительной цифрой, полученной с du /path/to/source(которая учитывает только данные файла). read_bytesи write_bytesвключать только то, что было прочитано или записано из хранилища, то есть исключает диагностику терминала и данные, уже находящиеся в кеше или все еще в буферах.

Жиль "ТАК - перестань быть злым"
источник
4
для реального времени:watch lsof -p1234
Mchid
3
Или все за один раз:watch lsof -p`pgrep -x cp`
Майк
15

Относительно новый инструмент, который делает именно это - прогресс (ранее cv [coreutils viewer]).

Что это такое?

Этот инструмент может быть описан как Tiny, Dirty, Linux-and-OSX-Only C команда, которая ищет основные команды coreutils (cp, mv, dd, tar, gzip / gunzip, cat и т. Д.), В настоящее время работающие в вашей системе, и отображает процент скопированных данных.

Как это работает?

Он просто сканирует /procинтересные команды, а затем смотрит на каталогах , fdи fdinfoнайти открытые файлы и искать позиции, а также отчеты о состоянии самого большого файла.

Амр Мостафа
источник
5
Этот утилит теперь называется прогресс: github.com/Xfennec/progress
Таави Ильвес
14

Один из моих любимых приемов для этого (под Linux) - узнать PID cpпроцесса (используя ps | grep cpили подобный), а затем посмотреть /proc/$PID/fd/и /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

Это покажет вам, какие файлы открыт у процесса. Если вы хотите увидеть, как далеко в файл идет процесс ...

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

posпараметром является положение указателя чтения (или записи), в байтах.

Jander
источник
7

Есть несколько вещей, которые вы можете сделать. Вы можете присоединиться straceк нему, чтобы посмотреть, что он делает (вывод может быть обильным!):

strace -p [pid of cp]

или вы можете lsofсказать, какие файлы открыты в данный момент:

lsof -p [pid of cp]

Если вы используете большой рекурсив cp, вы можете использовать pwdxтекущий рабочий каталог, который может дать вам некоторое представление о том, как он работает:

pwdx [pid of cp]
Flup
источник
4

Несмотря на то, что OP особо упомянул способность видеть, как продвигается команда «cp», следует сказать, что другие утилиты лучше подходят для этой конкретной проблемы.

Например:

rsync -avP FROM TO

покажет процесс копирования файла / папки FROM в файл 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

И rsync скажет вам, сколько он скопировал (и скорость передачи) по пути. Он работает для отдельных файлов или папок на одном компьютере или в сети.

Гордон МакКрей
источник
2
Вы отвечаете не на тот вопрос. Вопрос, который вы ищете: unix.stackexchange.com/questions/2577/… , в котором уже есть ответ с упоминанием rsync.
Муру
1

Что вы можете сделать, это проверить файлы в месте назначения.

Если ваши команды cp похожи, cp -a <my_source> <my_dest_folder>я бы проверил, какие файлы уже скопированы <my_dest_folder>и каждый размер файла, чтобы я мог видеть прогресс. Если <my_source>это немного сложно (несколько уровней каталогов), то небольшой сценарий сможет проверить состояние. Хотя такой сценарий может потреблять немного ввода-вывода, который затем не будет использоваться cpпроцессом.

Гюйгенс
источник
1

Этот инструмент представляет собой команду утилиты Linux, которая ищет основные команды coreutils (cp, mv, dd, tar, gzip / gunzip, cat и т. Д.), Которые в настоящее время выполняются в вашей системе, и отображает процент скопированных данных:

https://github.com/Xfennec/cv

Саиди
источник
1

Я хотел бы добавить cpv, небольшую обертку для того, pvчто я написал, которая имитирует использование cp.

Просто и полезно

введите описание изображения здесь

Вы можете получить это здесь

nachoparker
источник
0

Вы также можете использовать pipeviewer .

for f in *; do
  pv $f > destination/$f
done
user77376
источник
0

Используйте pv -d:

-d PID[:FD], --watchfd PID[:FD]
Вместо передачи данных просмотрите файловый дескриптор FDпроцесса PIDи покажите его ход. […] Если PIDуказан только a , то этот процесс будет отслеживаться, и все обычные файлы и блочные устройства, которые он открывает, будут отображаться с индикатором выполнения. pvПроцесс будет выходить , когда процесс PIDзавершается.

( источник )

Узнайте PID вашего бега cp( pidof cp), скажем, это 12345; тогда просто

pv -d 12345

Примечания:

  • Запуск pvот имени того же пользователя, который запускается cp(или от имени пользователя root).
  • Поскольку копирование означает чтение одного файла и запись в другой, ожидайте одновременного отслеживания двух файлов.
  • Если cpв данный момент выполняется обработка небольших файлов, вы, вероятно, не увидите их все в выводе (маленький файл может закрыться слишком быстро, pvчтобы его можно было поднять). Тем не менее, некоторые появятся, так что даже тогда вы сможете рассказать, что cpделает.
  • pv -d "$(pidof cp)"может работать; но если работает более одного cp, это не сработает. Существует, pidof -sкоторый возвращает не более одного PID, но вы не можете быть уверены, что он будет принадлежать правильному cpпроцессу, если их много.
Камиль Мачоровски
источник
-1

Вы можете отправить сигнал процессу:

kill -SIGUSR1 pid

Еще полезнее создать скрипт, который будет опрашивать, пока вы не нажмете Ctrl-C или процесс не завершится:

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

Работает на дд. Не работает для cp . Возможно, вам придется использовать другой сигнал. Однажды я попробовал SIGINFO, но, похоже, он больше не существует на платформе Intel.

JPT
источник