使用 su -c 时抛出错误:bash:此 shell 中没有作业控制

使用 su -c 时抛出错误:bash:此 shell 中没有作业控制

我编写了一个脚本,该脚本应该以另一个用户的身份执行某些命令,并且在执行完成后(成功或失败)应该立即注销。

我读到可以使用-cofsu来执行命令。所以,我写了一个像这样的脚本:

#!/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

因此,每当我尝试通过-cof运行某些脚本时su,它都会显示上述错误。我已经尝试了许多-c带有选项的命令,例如lswhichbash --versionmkdir、等rmwhoami所有这些命令都产生了正确的输出。但是任何尝试执行脚本的命令都会失败并出现错误。

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

相关内容