我编写了一个脚本,该脚本应该以另一个用户的身份执行某些命令,并且在执行完成后(成功或失败)应该立即注销。
我读到可以使用-c
ofsu
来执行命令。所以,我写了一个像这样的脚本:
#!/usr/bin/env bash
su - user2 -c "echo 'hurray' && exit"
它执行echo
命令,但保持登录状态,user2
不会注销。我什至尝试使用logout
而不是exit
但它保持登录状态。我需要执行脚本 asuser1
调用su
命令并执行 as user2
,然后控件应该user1
在完成后返回。
更新
好吧,我本来可以自动注销,但这次有些命令没有被执行。例如:
命令1:
su user2 -c 'echo 1'
输出1:
1
然后它会自行注销。
命令2:
su user2 -c 'bash some-script.sh'
输出2:
bash: cannot set terminal process group (-1): Inappropriate ioctl for device
bash: no job control in this shell
因此,每当我尝试通过-c
of运行某些脚本时su
,它都会显示上述错误。我已经尝试了许多-c
带有选项的命令,例如ls
、which
、bash --version
、mkdir
、等rm
。whoami
所有这些命令都产生了正确的输出。但是任何尝试执行脚本的命令都会失败并出现错误。
su user2 -c 'bash --version' # Works
su user2 -c 'bash some-script.sh' # Doesn't work
我不明白为什么会发生这种情况。这也是我无法修复此错误的原因。
答案1
最新版本的手册页中记录了此行为的原因su
:
-c, --command 命令
指定将由 shell 使用其
-c
.执行的命令将无控制终端。此选项不能用于执行需要控制 TTY 的交互式程序。
(强调我的)
ls
当您运行、echo
或等基本命令时bash --version
,它们只需将输出打印到stdout
流中,而不需要控制终端。
我怀疑该方式bash
正在被调用(作为交互式 shell)或some-script.sh
包含需要控制终端设备的命令,因此运行'bash some-script.sh'
会引发cannot set terminal process group (-1): Inappropriate ioctl for device
错误。
一些解释
A控制终端对于进程来说,是启动该进程的终端设备。控制终端可以向进程组发送信号,是 Unix 操作系统中作业控制的工作机制;作业控制允许进程组中的进程在前台或后台运行。
命令的输出ps
显示每个进程的控制终端,例如,
$ ps
PID TTY TIME CMD
3614 pts/5 00:00:00 bash
31628 pts/5 00:00:00 ps
su 最近的变化
过去,su -c
在不运行交互式 shell 时确实会启动控制终端。在我的 Ubuntu 系统上运行apt-get changelog login
显示,控制终端的删除是在 2012 年 5 月作为安全措施引入的:
- su:通过在执行命令时删除控制终端来修复可能的 tty 劫持 (CVE-2005-4890)。关闭:#628843