我有一个从终端运行时正常执行的 bash 脚本 postinstall.sh
./postinstall.sh
该脚本运行一系列命令,创建目录、chown、chmod 文件和目录,
在脚本的末尾是
echo "Done"
exit 0
当我在 go 中将其作为 exec.Cmd 运行并调用 cmd.Wait() 函数时,它永远不会返回。
所以我修改了我的代码以使用来自https://github.com/go-cmd/cmd的包,因为我希望能够记录我“实时”运行的脚本的输出,但也可以检测它们何时完成. 因此,经过一系列工作后,我现在可以将 Cmd 的 stdOut 记录到我的 logLevel STATUS 日志中,并将 Cmd 的 stdErr 记录到我的 logLevel ERROR。我还可以为命令设置超时,并实时记录其进度。
这个新进程在一些简单的情况下按预期工作,但是当我向它扔大 postinstall.sh 脚本时,它一直运行到最后,然后挂起,最终超时。在命令行上手动运行时,该过程需要几秒钟,我将超时设置为 30 秒。日志记录显示
STATUS- Done
就在
exit 0
go-cmd 包的文档显示了一种非锁定方式来告诉进程已经完成,我正在检查(并处理我的测试用例)我也在检查 cmd.Status().finished 标志(bool)并且两者都没有其中报告该过程已完成。这与我通过使用内置 exec.Cmd 中的 cmd.Wait() 函数看到的结果相同,直到现在我才能看到脚本一直到最后,但由于某种原因不是正在返回,或者 go 程序无法判断已经返回。
该脚本正在做的一些事情是在 /etc/init.d 中启动或重新启动服务,如果其中一个在后台启动一个进程,因为父进程是安装后脚本,这可能会导致该进程在围棋之眼?
或可能导致此类行为的任何其他类型的命令?
我可能只需要开始删除部分脚本,看看我是否可以完成它以缩小导致它与我的测试脚本不同的原因,但它大约有 100 行,以及将脚本放入设备是一个多步骤的过程。
testscript 类似于
#!/bin/bash
echo "stdOut"
sleep 1
>2& echo "stdErr"
sleep 2
echo "Finsihed"
sleep 1
这按预期工作(限制为 1 秒时超时,超时设置为 4 秒时显示完成)
还应注意该过程适用于其他脚本。这是执行 preinstall.sh 的更新过程的一部分,然后使用相同的过程对包含更新的文件调用 tar -xvf,然后继续执行此安装后脚本。所以大多数时候我的进程成功检测到进程已经退出,这就是安装后的问题,但我想不出是什么让它挂起,但从终端运行时退出正常。
心有法竹
相关分类