2017-05-29 16 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工具。 –