假设我运行,那么我可以通过变量time ./a.out
获取PID 。但是我如何获得 PID 呢?time
$!
a.out
当然,我可以解析 的输出ps
,但我想要一个更优雅的解决方案。
我检查过man time
,但找不到任何东西。
我得到的最接近的是time (sleep 10 & echo $!)
,但是由于分叉,所花费的时间基本上是 0 而不是应有的 10 秒。
答案1
根据定义,a.out
是 的子进程time
。time
的父进程 pid也是a.out
!下面是一个测试,我将 替换a.out
为sleep 60
:
$ time sleep 50 & timepid=$!
$ aoutpid=$(pgrep -P $timepid)
$ ps -o ppid,pid,start,cmd w -p $$,$timepid,$aoutpid
PPID PID STARTED CMD
2065 2068 21:34:57 -bash
2068 3297 22:16:05 -bash
3297 3298 22:16:05 sleep 50
(注意:wheretime
实际上是 shell 内置命令,所以上面的命令是bash
!)
答案2
如果启动 shell 的时间与运行命令所需的时间相比可以忽略不计,则可以运行中间 shell,并使用内置命令exec
来确保a.out
替换 shell,而不是作为子进程执行。
time sh -c 'echo $$; exec ./a.out'
答案3
答案4
可以通过编写一个小的 shell 片段来将其命令行的其余部分作为子进程运行,捕获该子进程的 PID 作为副作用。
这是一个可以为您执行此操作的脚本(为简洁起见,省略了错误检查)
#!/bin/sh
#
"$@" &
CHILD=$!
echo "$CHILD" >/tmp/mychild.pid
echo "INFO: child is $CHILD" >&2
wait
如果您要命名它,whatsmychild
那么您将在您的场景中使用它,如下所示:
time whatsmychild a.out
有证据表明它有效吗?这是另一个脚本;我们称这个为whatsmypid
:
#!/bin/sh
#
echo "My PID is $$" >&2
exit 0
现在我们将运行它:
$ time identifymychild whatsmypid
INFO: child is 8105
My PID is 8105
real 0m0.006s
user 0m0.000s
sys 0m0.000s
$ cat /tmp/mychild.pid
8105