通过附加到当前 tty 的 su 运行heredoc脚本

通过附加到当前 tty 的 su 运行heredoc脚本

我正在尝试做这样的事情:

sudo su <<EOF
select x in a b c; do echo "Selected $x"; break; done
EOF

但是,它会终止而不接受输入。

如果我这样做,它会起作用:

sudo su -c 'select x in a b c; do echo $x; break; done'

但用heredoc编写更长的脚本会更好(是的,我知道将它们放在文件中更好)。

我确信这个问题在各个地方都有答案,但我似乎无法找到正确的 bash/heredoc/tty/stdin 搜索词组合。

有什么办法可以实现这一点吗?

答案1

问题是select尝试从标准输入读取,该标准输入被重定向到此处文档。由于没有对提示做出响应,因此会出现错误。

解决方案是将输入重定向回此处文档中的终端。

sudo -s <<'EOF'
select x in a b c; do 
    echo "Selected $x"
    break
done </dev/tty
EOF

另外,您需要在引号中加上引号,EOF以防止变量在 here-doc 中扩展。否则,它会$x在原始 shell 中扩展,而不是在获取值的子 shell 中扩展select

答案2

如果您希望其余部分作为其他内容运行,则使用文件的一种方法

$ cat asdf
who am i
sudo su
who am i
$ bash < asdf
jhldoe   tty??    Jun  7 16:30 
root     tty??    Jun  7 16:30 
$ 

更简单的可能是给定标准输入的 shell 将运行这些命令

$ sudo sh <<EOF
> who am i
> pwd
> EOF
root     tty??    Jun  7 16:31 
/var/tmp
$ 

对于从标准输入读取并访问终端的问题,我可以用我的解决方案feed脚本 (文档,单元测试,.feedrcroot 的主目录的文件)。

$ (echo 'select x in a b c; do echo "Selected $x"; break; done') | sudo feed - bash

尽管这将使您处于根 shell 中,并将输入推入该 shell,因此可能适合也可能不适合您的需要。

相关内容