一旦用户终止命令,防止 GNU 屏幕终止会话

一旦用户终止命令,防止 GNU 屏幕终止会话

我试图在屏幕中运行命令,但一旦我在屏幕中使用 Ctrl-C 杀死子进程,就阻止它结束会话,就像这样: https://unix.stackexchange.com/a/47279/79125,但就我而言,该命令以不同的用户身份运行,并且我想在 Ctrl-C 子进程时返回 shell。这是我不成功的尝试

$ screen -S mySession -X screen -t tab3   sh  -c ' su - appuser -c "cd /appdir/bin; ./app start; bash"'

$ screen -S mySession -X screen -t tab6   su - appuser -c "sh -c 'cd /appdir/bin; ./app start; exec bash'"

$ screen -S mySession -X screen -t tab6   sh -c "su - appuser -c 'cd /appdir/bin; ./app start; exec bash'" 

$ screen -S mySession -X screen -t tab6   sh -c "su - appuser -c 'cd /appdir/bin; ./app start; exec bash'; su - someuser -c 'exec bash'"

答案1

信号处理

问题是外壳和应用程序都接收到信号。外壳可能不会简单地忽略该信号,因为它的子进程也会忽略该信号。

解决方案是使用信号处理程序将信号传递到应用程序:

bash -cm 'trap "kill -INT \$KILLPID" int; /bin/sleep 5 & KILLPID=$!; fg; /bin/echo foo'

-m是必需的,因为默认情况下,非交互式 shell 的作业控制处于禁用状态。

完整命令(未测试):

screen [...]  su - appuser -c bash -c 'cd /appdir/bin; ./app start & KILLPID=$!; trap "kill -INT $KILLPID" int; fg; bash'

答案2

您需要首先创建选项卡,然后使用 告诉 screen 在其中运行某些内容-X stuff

例如:

#!/bin/bash

# start a new detached screen, create windows named tab3 and tab6
# with appuser's $SHELL running in them, running as user "appuser".
screen -c /dev/null -d -m -S mySession
screen -c /dev/null -S mySession -X screen -t tab3 sudo -u appuser -i
screen -c /dev/null -S mySession -X screen -t tab6 sudo -u appuser -i

# as root, you could use `su - appuser`, instead of sudo but that
# would ask for a password if this is run as non-root user.  sudo
# can be configured to not ask for a password if required.   

# run some programs in the already-created tab3 and tab6
# using screen's "stuff" command.
screen -c /dev/null -S mySession -p tab3 -X stuff $'top\n'
screen -c /dev/null -S mySession -p tab6 -X stuff $'htop\n'

您可以使用例如 附加到该屏幕screen -S mySession -d -RR。如果您从任一选项卡tophtop在各自的选项卡中退出,这些选项卡将不会关闭,它们将返回应用程序用户的外壳提示符。

我在这里使用-c /dev/null它来阻止屏幕读取我的~/.screenrc,这会创建一堆选项卡并按照我想要的方式设置所有内容。或者曾经想要它,我tmux在使用了几十年后大约一年前切换到了它screen

另一种方法是创建一个新的 screenrc 文件,其中包含所需的命令screenstuff命令,然后运行screen -c /path/to/newscreenrc

相关内容