我有两个脚本。这些都被简化了。 root-script.sh
调用 userscript.sh
:
root-script.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
身份调用 root-script.sh
并输入 Ctrl-C 我会得到
enter x for exit: ^C
Session terminated, killing shell... ...killed.
然后我恢复了 root 提示符,但提示符被阻止了。 使用 ps 我看不到根脚本,只能看到用户脚本。 如果我终止用户脚本,根提示符将再次可用。
如何防止 root-script-user-script-construction 在 SIGINT 之后挂起? 对我来说意味着
- 退出
root-script.sh
和user-script.sh
或 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
最佳答案
我刚刚测试过:
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 处理程序。
希望这对您有用。
编辑:
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'
如果你想完全继承脚本的陷阱行为。
关于bash - 如何防止通过 su -c 调用的 bash 脚本在 SIGINT 后挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21074026/