2

我有两个脚本。这些都被简化了。root-script.sh来电userscript.sh:_

根脚本.sh:

 #!/bin/bash 
 su - user1 -c "/user1path/user-script.sh"

用户脚本.sh:

 #!/bin/bash
 trap 'echo please use x for exit' 2
 while x=0; do
    read -p "enter x for exit:" answer
    if [[ $answer = 'x' ]]; then
            echo "exit now"
            exit 0
    fi
 done

如果我调用 user-script.sh 它就可以正常工作:

 enter x for exit:
 enter x for exit: ^C_please use x for exit
^C_please use x for exit
x
exit now

如果我调用root-script.shasroot并输入 Ctrl-C 我得到

 enter x for exit: ^C
Session terminated, killing shell... ...killed.

比我找回根提示符,但提示符被阻止了。使用 ps 我看不到根脚本,只有用户脚本。如果我终止用户脚本,则根提示符将再次可用。

如何防止 root-script-user-script-construction 在 SIGINT 之后挂起?对我来说意味着

  1. 退出root-script.shuser-script.sh
  2. root-script-user-script-construction 应该与user-script.sh

    • bash 版本:3.2.51(1)-release (x86_64-suse-linux-gnu)
    • 操作系统版本:sles11 3.0.93-0.8-default
4

2 回答 2

1

我刚刚测试过:

su -c 'trap /bin/true 2; while true; do sleep 1; done' user

诗句

su -c 'while true; do sleep 1; done' user

并发现前者无法通过 SIGINT 终止,但后者可以。我的猜测是,也许 su -c 打开用户的 shell 以运行 -c 传递的命令,这就是捕获 SIGINT 并终止的原因 - 但你的脚本只在子 shell 中捕获 SIGINT - 这可能由 SIGTERM 传递父 shell 的 SIGINT 处理程序。

希望这对你有用。

编辑:

su -c 'echo $0; echo $SHELL' user

确认该命令是使用用户的 shell 运行的。

也许你会发现

su -c 'exec my_script.sh' user

成为一个更优雅的解决方案。我认为它会起作用,但尚未测试过。不过, exec 将用您的脚本进程替换当前的 shell 进程,所以我认为它应该可以工作。

编辑2:

回顾您的问题,我认为您只需要根脚本中的陷阱。或者可能:

exec 'su -c "exec script.sh" user'

如果你想完全继承脚本的陷阱行为。

于 2014-01-12T13:13:34.230 回答
1

这篇文章解释了为什么不传入 SIGINTsu -c并给出了解决方案:

http://sethmiller.org/it/su-forking-and-the-incorrect-trapping-of-sigint-ctrl-c/

在你的情况下:su - user1 --session-command "/user1path/user-script.sh"

作为--session-command一个不鼓励的选项(请参阅man su),如果您觉得不安全,也可以在您的情况下使用该-s选项:

su - user1 -s /user1path/user-script.sh

于 2017-05-08T17:13:42.383 回答