运行较长的命令时延迟创建输出文件

运行较长的命令时延迟创建输出文件

情况:我正在运行一个 shell 脚本。每当一个文件出现在 中时/etc/scripts,shell 脚本就会将chmod其设置为可执行文件,然后运行它。然后它会将其错误和输出重定向到其他 2 个文件中。

示例:1000.run出现。Shell 脚本获取 1000.run,使其可执行,运行它,并将其输出重定向到 1000.out 和 1000.err:

chmod +x 1000.run
sudo -u pi ./1000.run 1>1000.out 2>1000.err

之后1000.out1000.err出现了,我有另一个脚本正在监视这些文件,然后读出输出和错误。

但是,我有一个问题:命令较长。请看以下内容1000.run

sleep 30 && ls

运行后立即出现./1000.run1000.out1000.err- 均为空。我的其他脚本获取这些文件并说“嘿,我们有输出,命令已完成”,并返回给我空输出(当我期待ls输出时)。

实际上,30 秒后,ls确实出现了输出,但此时我的程序已经读入outerr文件并得出结论,实际上没有收到任何输出。

问题1000.out:有没有办法可以延迟重定向文件(和)的创建,1000.err直到整个命令运行完成?

到目前为止我尝试过

  • 我曾尝试使用stdbuf -o0(来自这里)。
  • 我曾尝试使用unbuffer(来自这里)。

答案1

您可以通过在输出文件附加表示脚本完成的字符串来解决此问题,例如“--end--”。

执行文件的脚本:

chmod +x 1000.run
sudo -u pi ./1000.run 1>1000.out 2>1000.err
"--end--" >> 1000.out

读取输出的伪代码:

fs.watch(pathToDirWithOutputsAndErrors, function (event, filename)  {
  if ( outputFile.lastLine == '--end--' ) {
    // script is done executing
    // do whatever...
  }
});

因此,只有输出文件的最后一行有“--end--”时,才会读取其输出。

注意:在if语句中确保仅检查 .out 文件中的“--end--”。

答案2

我认为您无法延迟文件创建直至它们被关闭,至少不能以一种简单的方式。

我将重写脚本,以便第二个脚本不会查找输出文件,而是查找指示命令已完成的标志文件。因此,最后您将拥有三个文件:1000.out1000.err1000.complete。该complete文件将写在脚本末尾,如下所示(假设每个要执行的文件都以 结尾.run):

FILE=1000.run

BASE=$(basename $FILE .run)
chmod +x $FILE

trap signalCompletion exit
function signalCompletion {
    touch $BASE.complete
}

sudo -u pi ./$FILE 1>$BASE.out 2>$BASE.err

使用trap命令创建文件可确保即使信号终止脚本,文件也会被创建。当第二个脚本检测到文件时.complete,它就知道读取和解析输出文件是安全的。

这并不能回答您的问题,但可能是您要解决的问题的解决方案。

相关内容