我有两个脚本。这些都是简化的。 root-script.sh
来电userscript.sh
:
root-script.sh:
#!/bin/bash
su - user1 -c "/user1path/user-script.sh"
user-script.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.sh
称为root
并输入Ctrl-C,我会
enter x for exit: ^C
Session terminated, killing shell... ...killed.
我回到root-prompt但是提示被阻止了。 使用ps我没有看到root脚本,只看到用户脚本。 如果我终止用户脚本,则根提示符可以再次使用。
如何在SIGINT之后阻止root-script-user-script-construction挂起? 对我来说意味着
root-script.sh
和user-script.sh
或 root-script-user-script-construction应该与user-script.sh
答案 0 :(得分:1)
本文解释了为什么SIGINT没有传递到su -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
答案 1 :(得分:0)
我刚刚测试过:
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 - 这可能是由父shell的SIGINT处理程序传递SIGTERM。
希望这适合你。
编辑:
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'
如果您想完全继承脚本的陷阱行为。