从 1 行 bash 调用获取 PID 并返回代码

从 1 行 bash 调用获取 PID 并返回代码

想象一下我们有一个很长的命令sleep 10(例如)。我们想使用 python(paramiko具体来说是 ssh 库)在另一台服务器上执行它。

我需要一个 1 行命令来启动命令,打印命令的 PID,然后等待它完成,最后返回命令的退出状态。

到目前为止我尝试过的:

bash -c "echo $BASHPID ; exec sleep 10" ; echo $?

这会打印 shell 的 PID,然后对长命令调用 exec,然后等待并打印退出状态。问题是$BASHPID打印外部 bash shell 的 PID(可能表明调用bash -c cmd实际上并没有生成一个完整的新 shell?)。

如果我用三行调用上面的命令,它就可以工作。

bash
echo $BASHPID ; exec sleep 10
echo $?

任何使用子外壳的尝试对我来说都不起作用。

echo $(echo $BASHPID ; exec sleep 10) ; echo $?

这是可行的,但是子 shell 将其所有输出通过管道传递给 echo,并且 echo 会立即打印所有内容,这意味着$BASHPID直到睡眠完成后才会打印。 PID 必须立即打印。

答案1

当你跑步时,例如:

bash -c“回显$BASHPID;执行睡眠10”

或者

回声 $(回声 $BASHPID ; 执行睡眠 10)

$BASHPID您当前的 shell正在第二个 bash(或子 shell)看到该变量之前插入该变量。解决方案是防止当前 shell 扩展这些变量:

bash -c 'echo $BASHPID ; exec sleep 10'

答案2

这是您已经运行过的 shell 命令ssh(由远程用户的登录 shell 解释),无需在此基础上启动另一个 shell。假设 shell 是类似 Bourne 或类似 csh 的:

echo "$$"; exec sleep 10

应该足够了。无需bash在远程主机上安装。ssh还会报告远程命令的退出状态,无需打印。但如果必须的话,你可以这样做:

sleep 10 & echo "$!"; wait; echo "$?"

$?不适用于类似 csh 的 shell $status

如果您不能保证远程用户的登录 shell 与 Bourne 类似,您可以这样做:

exec sh -c 'sleep 10 & echo "$!"; wait; echo "$?"'

该命令至少应该与 Bourne、csh 和 rc 系列的 shell 兼容。

相关内容