基于 PID 的标准输出 (OSX)
Stdout based on a PID (OSX)
我正在使用许多单独的脚本处理许多文件。为了加快处理速度,我使用 &
将它们置于后台,但是这样我就无法跟踪它们在做什么(我看不到输出)。
有没有一种简单的方法可以根据 PID 获取输出?我找到了一些基于 fg [job number]
的答案,但我无法从 PID 中找出工作编号。
后台脚本通常会继续写入标准输出;如果你 运行 几个,他们将全部倾销他们的输出相互混合。而是将它们转储到文件中。例如,使用 $$
(当前进程 ID)生成输出文件名并写入该文件。
outfile=process.$$.out
# ...
echo Output >$outfile
将写信给 process.27422.out
。
您可以考虑 运行 您的脚本,从 screen
然后 return 到他们,只要您愿意:
$ screen ./script.sh
至 "detach" 并保留脚本 运行 按 ControlA 然后按 控制D
$ screen -ls
将列出您的屏幕会话
$ screen -r <screen pid number>
Returns 屏幕会话
上面的几个命令几乎没有触及 screen 的功能,因此请查看有关它的手册页,您可能会对它的所有功能感到惊讶。
其他用户的回答是正确的 - exec &>$outfile
或 exec &>$outfifo
或 exec &>$another_tty
是您需要做的,也是正确的方法。
但是,如果您已经启动了脚本,则可以使用一种解决方法。我写了这个脚本来将任何 运行 进程的 stdout
/stderr
重定向到另一个 file/terminal.
$ cat redirect_terminal
#!/bin/bash
PID=
stdout=
stderr=${3:-}
if [ -e "/proc/$PID" ]; then
gdb -q -n -p $PID <<EOF >/dev/null
p dup2(open("$stdout",1),1)
p dup2(open("$stderr",1),2)
detach
quit
EOF
else
echo No such PID : $PID
fi
示例用法:
./redirect_terminal 1234 /dev/pts/16
其中,
1234
是脚本进程的PID。
/dev/pts/16
是另外一个单独打开的终端
请注意,此更新的 stdout/stderr 不会继承给该进程的已经 运行 个子进程。
考虑使用 GNU Parallel - 它很容易安装在 OSX 和 homebrew
上。它不仅会标记您的输出行,还会使您的 CPU 忙碌,在前一个工作完成后立即安排另一个工作。您可以使用替换参数组成您自己的标签。
假设您有 20 个名为 file{10..20}.txt
的文件需要处理:
parallel --tagstring "MyTag-{}" 'echo Start; echo Processing file {}; echo Done' ::: file*txt
MyTag-file15.txt Start
MyTag-file15.txt Processing file file15.txt
MyTag-file15.txt Done
MyTag-file16.txt Start
MyTag-file16.txt Processing file file16.txt
MyTag-file16.txt Done
MyTag-file17.txt Start
MyTag-file17.txt Processing file file17.txt
MyTag-file17.txt Done
MyTag-file18.txt Start
MyTag-file18.txt Processing file file18.txt
MyTag-file18.txt Done
MyTag-file14.txt Start
MyTag-file14.txt Processing file file14.txt
MyTag-file14.txt Done
MyTag-file13.txt Start
MyTag-file13.txt Processing file file13.txt
MyTag-file13.txt Done
MyTag-file12.txt Start
MyTag-file12.txt Processing file file12.txt
MyTag-file12.txt Done
MyTag-file19.txt Start
MyTag-file19.txt Processing file file19.txt
MyTag-file19.txt Done
MyTag-file20.txt Start
MyTag-file20.txt Processing file file20.txt
MyTag-file20.txt Done
MyTag-file11.txt Start
MyTag-file11.txt Processing file file11.txt
MyTag-file11.txt Done
MyTag-file10.txt Start
MyTag-file10.txt Processing file file10.txt
MyTag-file10.txt Done
如果你想按顺序输出,使用parallel -k
保持输出顺序
如果您想要进度报告,请使用parallel --progress
如果您想要记录工作时间 started/ended,请使用 parallel --joblog log.txt
如果您想 运行 32 个作业并行,而不是每个 CPU 核心默认 1 个作业,请使用 parallel -j 32
作业日志示例:
Seq Host Starttime JobRuntime Send Receive Exitval Signal Command
6 : 1461141901.514 0.005 0 38 0 0 echo Start; echo Processing file file15.txt; echo Done
7 : 1461141901.517 0.006 0 38 0 0 echo Start; echo Processing file file16.txt; echo Done
8 : 1461141901.519 0.006 0 38 0 0 echo Start; echo Processing file file17.txt; echo Done
我正在使用许多单独的脚本处理许多文件。为了加快处理速度,我使用 &
将它们置于后台,但是这样我就无法跟踪它们在做什么(我看不到输出)。
有没有一种简单的方法可以根据 PID 获取输出?我找到了一些基于 fg [job number]
的答案,但我无法从 PID 中找出工作编号。
后台脚本通常会继续写入标准输出;如果你 运行 几个,他们将全部倾销他们的输出相互混合。而是将它们转储到文件中。例如,使用 $$
(当前进程 ID)生成输出文件名并写入该文件。
outfile=process.$$.out
# ...
echo Output >$outfile
将写信给 process.27422.out
。
您可以考虑 运行 您的脚本,从 screen
然后 return 到他们,只要您愿意:
$ screen ./script.sh
至 "detach" 并保留脚本 运行 按 ControlA 然后按 控制D
$ screen -ls
将列出您的屏幕会话
$ screen -r <screen pid number>
Returns 屏幕会话
上面的几个命令几乎没有触及 screen 的功能,因此请查看有关它的手册页,您可能会对它的所有功能感到惊讶。
其他用户的回答是正确的 - exec &>$outfile
或 exec &>$outfifo
或 exec &>$another_tty
是您需要做的,也是正确的方法。
但是,如果您已经启动了脚本,则可以使用一种解决方法。我写了这个脚本来将任何 运行 进程的 stdout
/stderr
重定向到另一个 file/terminal.
$ cat redirect_terminal
#!/bin/bash
PID=
stdout=
stderr=${3:-}
if [ -e "/proc/$PID" ]; then
gdb -q -n -p $PID <<EOF >/dev/null
p dup2(open("$stdout",1),1)
p dup2(open("$stderr",1),2)
detach
quit
EOF
else
echo No such PID : $PID
fi
示例用法:
./redirect_terminal 1234 /dev/pts/16
其中,
1234
是脚本进程的PID。
/dev/pts/16
是另外一个单独打开的终端
请注意,此更新的 stdout/stderr 不会继承给该进程的已经 运行 个子进程。
考虑使用 GNU Parallel - 它很容易安装在 OSX 和 homebrew
上。它不仅会标记您的输出行,还会使您的 CPU 忙碌,在前一个工作完成后立即安排另一个工作。您可以使用替换参数组成您自己的标签。
假设您有 20 个名为 file{10..20}.txt
的文件需要处理:
parallel --tagstring "MyTag-{}" 'echo Start; echo Processing file {}; echo Done' ::: file*txt
MyTag-file15.txt Start
MyTag-file15.txt Processing file file15.txt
MyTag-file15.txt Done
MyTag-file16.txt Start
MyTag-file16.txt Processing file file16.txt
MyTag-file16.txt Done
MyTag-file17.txt Start
MyTag-file17.txt Processing file file17.txt
MyTag-file17.txt Done
MyTag-file18.txt Start
MyTag-file18.txt Processing file file18.txt
MyTag-file18.txt Done
MyTag-file14.txt Start
MyTag-file14.txt Processing file file14.txt
MyTag-file14.txt Done
MyTag-file13.txt Start
MyTag-file13.txt Processing file file13.txt
MyTag-file13.txt Done
MyTag-file12.txt Start
MyTag-file12.txt Processing file file12.txt
MyTag-file12.txt Done
MyTag-file19.txt Start
MyTag-file19.txt Processing file file19.txt
MyTag-file19.txt Done
MyTag-file20.txt Start
MyTag-file20.txt Processing file file20.txt
MyTag-file20.txt Done
MyTag-file11.txt Start
MyTag-file11.txt Processing file file11.txt
MyTag-file11.txt Done
MyTag-file10.txt Start
MyTag-file10.txt Processing file file10.txt
MyTag-file10.txt Done
如果你想按顺序输出,使用
parallel -k
保持输出顺序如果您想要进度报告,请使用
parallel --progress
如果您想要记录工作时间 started/ended,请使用
parallel --joblog log.txt
如果您想 运行 32 个作业并行,而不是每个 CPU 核心默认 1 个作业,请使用
parallel -j 32
作业日志示例:
Seq Host Starttime JobRuntime Send Receive Exitval Signal Command
6 : 1461141901.514 0.005 0 38 0 0 echo Start; echo Processing file file15.txt; echo Done
7 : 1461141901.517 0.006 0 38 0 0 echo Start; echo Processing file file16.txt; echo Done
8 : 1461141901.519 0.006 0 38 0 0 echo Start; echo Processing file file17.txt; echo Done