所以最近我一直试图通过“退出”命令以干净的方式退出正在运行的进程。如果我不完成整个退出过程,它会创建一个 .lck 文件,而我不想要这个。
我一直无法成功,我尝试了多种方法,例如呼应“退出”和\015、\012、\n到/proc/pid/fd/0,但这些都无法验证缓冲区中的内容。我尝试筛选终端,并将进程复制到其中,以便它进入终端,但这样做我找不到模拟回车键的方法。
因此,由于似乎无论我尝试什么都找不到如何验证文本缓冲区,我决定应该直接使用内置退出而不是尝试输入它。
有没有办法直接使用另一个进程命令?当我尝试
quit | reptyr <process pid>
例如,它说 quit 不是一个可识别的命令,因为 shell 正试图在它自己的环境中执行它,而我希望在其他进程环境中执行它。
注意:关于所述正在运行的过程的一些信息,我必须提供几个输入才能退出它。
按 Ctlr + C 停止它,然后切换到 SimDebug 模式,该模式仅提供信息,我应该按几次回车键。它在读取模式下看起来像
模拟调试>
我应该在那里写下退出并按回车键,然后按 q 并按回车键,按 n 并按回车键,最后按回车键。
我设法在脚本中使用 kill -INT 来完成第一点,其余部分则保持不变。
编辑:我可以按照建议使用 SIGTERM 跳过其中一些任务,尽管它让我读到最后
您是否要进行检查点 (Y/N) _
我无法再执行 SIGTERM,SIGKILL 会弹出错误消息并创建一个 .lck 文件。我只需要在里面输入“n”或“y”。我会看一下 expect,因为现在我有这个问题,但我仍然想知道如何使用它来监听进程而不是我运行脚本的终端。
答案1
运行程序tmux
(或者,如果需要,运行来“劫持”已经运行的进程;例如reptyr
)。然后,您可以从另一个终端执行以下操作:tmux
tmux new-session reptyr "$pid_to_hijack"
pane='$0:@0.1'
tmux send-keys -t "$pane" C-c # a way to send Ctrl+C
sleep 2 # let the program react (you may or may not need it)
tmux send-keys -t "$pane" Enter Enter Enter # "should I press enter a few times"
tmux send-keys -t "$pane" quit Enter # "I should write quit and press enter"
tmux send-keys -t "$pane" q Enter # "then q and enter"
tmux send-keys -t "$pane" n Enter # "n and enter"
tmux send-keys -t "$pane" Enter # "then lastly enter"
其中示例$0:@0.1
标识了程序运行的窗格(必须用单引号括住此字符串,否则 shell 将扩展$0
)。如果您命名了 tmux 会话和窗口,则此字符串可能类似于mysession:mywindow.0
。
答案2
据我了解,您正在尝试将命令发送到“子 shell”。比如说quit()
在 python shell 中运行命令?或者任何其他等待输入的程序?
如果这就是你想要的,我想你正在寻找类似的东西:
$> python <<< "quit() python <<< "<many instructions here>" python <
$> file_containing_instructions.py #with quit() at the end python << END
$> <instructions> <on_many_lines> END
现在,如果您尝试保留对正在运行的进程的引用,然后稍后向其发送指令,那么目前我唯一能告诉您的就是coproc
。您可以通过了解一些相关信息help coproc
,更多信息请参见man bash
,甚至更多信息请参见info bash
。
祝你好运
编辑:刚刚回到该选项卡,看到糟糕的格式,所以我修复了它。另外,我想补充一点,我还没能用 Python 让它工作,但很可能是可行的,尽管用其他 shell 比如 bash 也可以这样工作。
$> coproc PRC { bash; } &
$> echo 'echo $PATH' >&${PRC[1]}
$> read -t1 -u ${PRC[0]} resp
$> echo $resp
/the/PATH/is/printed
$> echo 'exit' >&${PRC[1]}
$> jobs
[1]+ Done