我正在編寫一些腳本,以便在運行 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