Linux

在沒有 USR1 的情況下檢查 dd 的進度?

  • November 3, 2021

我在一個busybox 1.27僅限 Linux 的系統上,所以沒有output=progress可用的,busybox 自己的實現也不pv是它本身。pipe_progress``pv

我有兩個問題。第一個基於https://www.linux.com/training-tutorials/show-progress-when-using-dd/。它說,通過向它發送USR1信號dd“暫停”該過程,並且dd在列印其目前狀態後將繼續它正在執行的工作。我正在嘗試進行一些基準測試,dd因此我希望對dd操作的影響最小。我想每秒獲得目前操作的輸出,因為通過的數據在dd波動,辨識傳輸速率何時下降對我來說很重要。

第一個問題: ‘dd’每次收到USR1信號時“暫停”是真的嗎?

如果dd每秒暫停一次,那麼當傳輸數十 GB 時,我將在操作中增加幾個小時。

第二個問題: 假設第一個問題的答案是肯定的,我想知道是否有可能在dd不向程序發送任何信號的情況下列印其目前狀態,也許是某種重定向STDOUT(如 2>&1)?

我指的是:

# bs with 1Mib so I can have more control on the test.
dd if=/dev/zero of=/dev/null bs=1048576 count=1024

# Printing current operation status.
sudo kill -USR1 $dd_pid 

dd if=/dev/zero of=/dev/null bs=1048576 count=1024

請注意,至少在使用參數時dd可以破壞數據。如果您為特定的系統配置手動選擇最佳塊大小,它的性能優勢充其量是很小的:或者可以做得更好,最多只是稍微慢一點。因此,如果您不需要,請不要使用。bscat``cp``dd

請注意,從 1.23 版開始,BusyBox 使用sendfile系統呼叫來複製數據,而不是使用readand write。只有普通副本,例如catand cpuse sendfile,但是:dd被迫使用read/write因為它想要精確控制大小。所以在 BusyBox ≥1.23 的情況下,catcp可能比dd.

‘dd’ 是否真的在每次收到 USR1 信號時“暫停”?

從技術上講是的,它必須“暫停”來處理信號。然而,暫停只是幾個 CPU 指令(迄今為止最昂貴的部分是列印進度輸出)。因此,這不會以任何方式使您的基準測試無效。

如果 dd 每秒暫停一次,那麼當傳輸數十 GB 時,我將在操作中增加幾個小時。

不,您的數量級錯誤。您可能會在單 CPU 執行緒上增加 0.1% 的時間。主要成本是基準測試程序的核心時間,而不是dd,因此它是您想要做的事情所固有的,而不是您實現它的方式。

如果有可能讓 dd 在不向程序發送任何信號的情況下列印其目前狀態

嗯,不。已經有一種簡單的、歷史悠久的、標準的、簡單的方法來做到這一點。為什麼會有另一種更難實施的方法?


在 Linux 上,有一種通用的方法可以知道副本到達的位置。它不依賴於正在執行複制的程序,儘管它並不總是適用於特殊文件。找出$pid正在進行複制的程序 ID,以及它用於輸入和輸出的文件描述符。dd從 fd 0 讀取並寫入 fd 1。BusyBoxcp通常從 fd 3 讀取並寫入 fd 4。您可以通過/proc/$pid/fd.

$ cp /dev/zero /dev/null & pid=$!
$ readlink /proc/$pid/fd/3
/dev/zero
$ readlink /proc/$pid/fd/4
/dev/null

您可以檢查文件描述符$n$/proc/$pid/fd/$n.

$ cat /proc/$pid/fdinfo/4
pos:    74252288
flags:  0100001
mnt_id: 27

但是,請注意,文件描述符位置可能不會使用特殊文件(例如/dev/zero/dev/null、管道或套接字)進行更新。它總是用正常文件更新。我不知道它是否針對塊設備進行了更新。因此,它可能不會為您提供在/dev/zeroand之間進行複制的任何資訊/dev/null,但它可能適用於您的實際案例。

引用自:https://unix.stackexchange.com/questions/675781