Я пишу несколько скриптов для установки некоторых вещей на сервер под управлением 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
Когда я запускаю скрипт, передавая в качестве параметра "[email protected]«Я получаю следующий вывод:
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-сервер порождает оболочку. Оболочка обрабатывает ваш here-документ, переданный с локальной стороны.
DEBIAN_FRONTEND=noninteractive
определяет переменную в оболочке. Переменная не экспортируется в среду. Она будет переменной среды, только если она уже является переменной среды; скорее всего, это не так.- Оболочка порождает (или выполняет)
sudo
. Наследуются только переменные окружения, поэтомуsudo
не знает вашDEBIAN_FRONTEND
. sudo
порождаетapt-get
. Даже если бы инструмент зналDEBIAN_FRONTEND
, это нормально дляsudo
дезинфекции среды его потомка, так что он все равноapt-get
не узнаетDEBIAN_FRONTEND
.
Чтобы справиться с этим, вам нужно экспортировать переменную. Вместо этого DEBIAN_FRONTEND=noninteractive
вам нужно отправить
export DEBIAN_FRONTEND=noninteractive
к удаленной оболочке. Затем вам нужно убедиться, 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
чтобы предотвратить расширение переменной на локальной стороне (или вам нужно экранировать $
). Это становится сложным, и хорошая новость в том, что вам вообще не нужна переменная в удаленной оболочке. В вашем случае этого должно быть достаточно, чтобы определить правильную переменную для apt-get
:
sudo DEBIAN_FRONTEND=noninteractive apt-get install --assume-yes docker.io
Наконец, в случае, если политика безопасности не позволяет вам указать эту переменную, вы можете создать sudo
еще одну оболочку:
sudo sh -c 'DEBIAN_FRONTEND=noninteractive apt-get install --assume-yes docker.io'
Но я полагаю, что такая ограничительная политика изначально не позволит вам участвовать sh
в гонке, поэтому последняя команда может не иметь практического значения.sudo