我正在尝试做这样的事情:
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
脚本 (文档,单元测试,.feedrc
root 的主目录的文件)。
$ (echo 'select x in a b c; do echo "Selected $x"; break; done') | sudo feed - bash
尽管这将使您处于根 shell 中,并将输入推入该 shell,因此可能适合也可能不适合您的需要。