2017-05-29 47 views
1

輸出我有這行代碼沿:獲取定時進程的PID,隨着時間

{ time cp $PWD/my_file $PWD/new_file ; } 2> my_log.log 

我需要知道需要多長時間來執行「CP」命令,我也需要得到'cp'的PID。我只是想打印的「CP」進程的PID,並獲得在my_log.log文件中的以下內容:

<output of time> 

我已經試過PID=$!但這並不提供cp進程的PID。

+0

你想知道CP的PID或在後臺運行的進程的PID?你是否正在複製大量文件? – LethalProgrammer

+0

這不是很清楚....你只需要日誌文件中'cp'進程的pid?你想輸出的時間到標準輸出嗎? –

回答

2
  • 首先,你需要你的(定時)cp命令發送到後臺與尾隨&,這樣你就可以啓動它後,檢查正在運行的進程。 (我懷疑你已經這樣做了,但目前還沒有反映在問題中)。

  • $!,包含最近啓動的後臺作業的PID,在這種情況下,特殊變量反映了子shell運行的time命令,所以我們知道它是cp過程命令。爲了得到(獨一無二的,在這種情況下)子進程:

    • 如果你的平臺具有非標準pgrep實用程序(附帶了許多Linux發行版和BSD/MacOS的平臺),用途:
      pgrep -P $!

    • 否則,請使用以下符合POSIX標準的做法:
      ps -o pid=,ppid= | awk -v ppid=$! '$2 == ppid { print $1 }'

爲了把它放在一起,使用prgep爲了方便:

# Send the timed `cp` command to the background with a trailing `&` 
{ time cp "$PWD/my_file" "$PWD/new_file"; } 2> my_log.log & 

# Get the `cp` comand's PID via its parent PID, $! 
cpPid=$(pgrep -P $!) 
0

我能想到的最簡單的是

pgrep cp 
+0

'(time cp $ PWD/my_file $ PWD/new_file & 2>&1; echo $!)> my_log.log 2>&1' my_log.log的內容將是cp命令的PID,後跟cp命令的計時輸出。 – Deathgrip

+0

行 - 將發佈答案。 – Jack

0

OK - 從評論:「my_log.log的內容將是cp命令,然後cp命令的時間輸出的PID」:

(time cp $PWD/my_file $PWD/new_file & 2>&1; echo $!) > my_log.log 2>&1 

首先,你需要使用/usr/bin/time明確,並通過選項追加到輸出文件。然後,在您要複製(cp會得到太多的碰撞)文件的名稱中使用pgrep

/usr/bin/time --output=my_log.log --append cp $PWD/my_file $PWD/new_file & pgrep -f my_file > my_log.log 

你可能想改變輸出格式,因爲它有點難看:

18400 
0.00user 0.30system 0:02.43elapsed 12%CPU (0avgtext+0avgdata 2520maxresident)k 
0inputs+496424outputs (0major+141minor)pagefaults 0swaps 
0

繼寫在上面您的評論的一個什麼......下面是一個合適的回答:

下面的代碼(只是一個例子):

time (sleep 10 & echo -n "$!"; wait) 

將返回類似:

30406 
real 0m10.009s 
user 0m0.004s 
sys 0m0.005s 

你的情況:

time (cp $PWD/old_file $PWD/new_file & echo -n "$!"; wait) &> my_log.log 

將做的工作。

我發現這個解決方案非常優雅,因爲它是一個「單線程」,儘管你在時間上有「完全可以忽略的開銷」(時間將與整個子shell相關(也是echowait)。開銷是可以忽略不計從睡眠命令的結果是顯而易見的。

&>重定向輸出和錯誤,以相同的文件(這樣你就不會需要指定1>&2)。

注重,這樣做

(time sleep 10 & echo -n "$!") 

您將得到time進程的pid,而不是sleepcp

2

知道你能大約需要多長時間cp命令檢查新文件的大小

size=$(stat -c %s "${old_file}") 
cp "${old_file}" "${new_file}" & 
cp_pid=$! 
while kill -0 ${cp_pid}; do 
    cpsize=$(stat -c %s "${new_file}") 
    echo elapsed time $(ps -p${cp_pid} -oetime=) 
    echo $((100*cpsize/size)) % done so far.. 
    sleep 3 
done 

編輯:以下評論stat -c %s "${file}"可以通過du "${file}"替代它的POSIX,更適合命令(請參見手冊頁)。

+0

很好地完成。值得一提的是'stat'不是POSIX實用程序,而在BSD/macOS上,您必須使用'stat -f%z'來代替。 – mklement0

+0

不錯的主意,但看起來與問題無關.... :) –

+0

爲什麼不使用'du $ {old_file}'而不是'stat'? 'du'應該是一個POSIX工具。 –