![我的顺序 bash 脚本显示非顺序行为](https://linux22.com/image/163868/%E6%88%91%E7%9A%84%E9%A1%BA%E5%BA%8F%20bash%20%E8%84%9A%E6%9C%AC%E6%98%BE%E7%A4%BA%E9%9D%9E%E9%A1%BA%E5%BA%8F%E8%A1%8C%E4%B8%BA.png)
我的 bash 脚本有问题,非常感谢您帮助找出问题。 bash 脚本脚本.sh如下:
#!/bin/bash
./command1 -i inFile.txt -o outFile1.bin > log1.txt
./command2 -i inFile.txt -o outFile2.txt > log2.txt
./command3 -i outFile2.txt -o outFile3.txt > log3.txt
...
这里,-i 定义输入文件,-o 定义输出文件。有一些依赖性,例如命令 2 的输出文件用作命令 3 的输入文件。
我使用调用脚本
nohup ./Script.sh > scriptLog.txt 2> scriptErr.txt &
这是发生的奇怪的事情:脚本运行完成,没有任何错误(scriptErr.txt 为空)。输出文件(outFile1.txt、outFile2.txt 和 outFile3.txt)已生成,并且据我所知是正确的。这工作命令显示运行已完成(Done)。命令
ps aux | grep ./Script.sh
不返回任何内容(仅返回 grep 本身)。然而,该命令
ps aux | grep ./command1
显示 command1 仍在运行(command2 和 command3 的情况并非如此)。这就是让我困惑的地方:
该脚本应该是连续的。怎么可能命令2和3已经完成而命令1还没有完成呢?
如果命令1没有完成,那么如何正确生成输出文件呢?
非常感谢!
答案1
这里的问题来自于nohup
+ &
。
您可以使用它们将进程发送到后台。&
还分叉您当前的进程。因此,Script.sh
您不会得到两个(或乘以您使用的次数&
)。新Script.sh
进程是您启动的进程的子进程。commandX
是从 forked 开始的Script.sh
。
一旦主脚本进程完成,父进程Script.sh
就会消失,所有子进程都会移至 init 进程。这些是不同的过程,只是名称匹配,可能会带来一些混乱。
答案2
构建一个尽管返回但仍保持运行的脚本很容易:
$ ./still_running
I'm done
$ ps aux | grep '[s]till_running'
anthony 25666 0.0 0.0 7420 2092 pts/31 S 16:43 0:00 /bin/bash ./still_running
该脚本相当简单:
#!/bin/bash
(
sleep 5m
echo 'done now'
) &
echo "I'm done"
它启动一个子 shell,该子 shell 在后台运行(由于&符号),并且即使父进程退出,它也会保持运行。
如果没有看到脚本(最好是最小的测试用例),就不可能确定脚本发生了什么,但是这种或类似的情况是有可能的。