我正在编写一些脚本以便在运行 Debian 10 的服务器上安装一些东西。
这是脚本:
#!/usr/bin/env sh
address=$1
ssh -T $address <<EOF > /dev/null
DEBIAN_FRONTEND=noninteractive
sudo apt-get install --assume-yes docker.io
EOF
当我运行作为参数传递的脚本时“[电子邮件保护]“我得到以下输出:
debconf: unable to initialize frontend: Dialog
debconf: (Dialog frontend will not work on a dumb terminal, an emacs shell buffer, or without a controlling terminal.)
debconf: falling back to frontend: Readline
debconf: unable to initialize frontend: Readline
debconf: (This frontend requires a controlling tty.)
debconf: falling back to frontend: Teletype
dpkg-preconfigure: unable to re-open stdin:
我的理解是,这DEBIAN_FRONTEND=noninteractive
是为了防止出现这些警告。我是不是误解了什么?
我也尝试过将命令放入脚本中并运行脚本而不是命令。然后我尝试不使用此文档,但仍然没有成功。
答案1
事情是这样的:
- 在远程端,SSH 服务器会生成一个 shell。该 shell 会处理从本地端传输过来的此处文档。
DEBIAN_FRONTEND=noninteractive
在 shell 中定义一个变量。该变量不会导出到环境中。只有当它已经是环境变量时,它才会成为环境变量;很可能它不是。- shell 生成 (或执行)
sudo
。仅继承环境变量,因此sudo
不知道您的DEBIAN_FRONTEND
。 sudo
产生apt-get
。即使该工具知道,清理其子进程的环境DEBIAN_FRONTEND
也是很正常的,所以无论如何都不会知道。sudo
apt-get
DEBIAN_FRONTEND
为了解决这个问题,你需要导出变量。而不是DEBIAN_FRONTEND=noninteractive
发送
export DEBIAN_FRONTEND=noninteractive
到远程 shell。然后你需要确保sudo
它不会隐藏apt-get
。请参阅此问题:使用时如何保留环境变量sudo
?来自其中一个答案:
你需要
man sudo
仔细阅读,并注意标志-E
。[…]以下是手册页中的引文:
-E
,--preserve-env
向安全策略表明用户希望保留其现有的环境变量。如果用户没有权限保留环境,安全策略可能会返回错误。
在你的情况下,这里的文档将是这样的:
export DEBIAN_FRONTEND=noninteractive
sudo -E apt-get install --assume-yes docker.io
另一个答案提到了一种在文件中指定无需-E
:即可保留的变量的方法。我不会对此进行详细说明。env_keep
sudoers
还有一种方法:sudo
允许您通过将变量放在实际命令之间来定义变量sudo
,尽管这些变量也受到安全策略的限制。即使不导出变量,以下代码片段也应该有效(如果策略允许):
DEBIAN_FRONTEND=noninteractive
sudo DEBIAN_FRONTEND="$DEBIAN_FRONTEND" apt-get install --assume-yes docker.io
注意,对于 here-document,您需要<<'EOF'
而不是 ,<<EOF
以防止本地端的变量扩展(或者您需要转义$
)。这变得很复杂,好消息是您根本不需要远程 shell 中的变量。在您的情况下,这应该足以为 定义正确的变量apt-get
:
sudo DEBIAN_FRONTEND=noninteractive apt-get install --assume-yes docker.io
最后,如果安全策略不允许您指定此变量,您可以生成sudo
另一个 shell:
sudo sh -c 'DEBIAN_FRONTEND=noninteractive apt-get install --assume-yes docker.io'
但我预计这种限制性政策首先会阻止你跑sh
进来,所以最后一条命令可能没有实际意义。sudo