Bash: sudo-S <<<“mypassword” - интерактивная проблема оболочки

Я пытаюсь использовать sudo с -S выпустить пароль через командную строку.

$ sudo -S <<< "mypassword" command

Это работает, но это не допускает интерактивные команды. Как nano например:

$ sudo -S <<< "mypassword" nano /tmp/foo

Это автоматически закрыло нано сеанс. То же с apt-get:

$ sudo -S <<< "mypassword" apt-get install foo

Это закрывается, прежде чем я смогу нажать "y" для установки нечто. Я знаю, что могу передать -y с Кв., но в целом, это печально.

Также испытанный материал как это, но этому все еще не удается взаимодействовать с интерактивной сессией:

$ sudo -S <<< "mypassword" -H -u root bash -c "apt-get install foo"

Действительно ли возможно использовать -S с sudo, не отменяя все интерактивные оболочки?

0
задан 25 February 2019 в 22:52

1 ответ

Дескрипторы файлов наследованы

То, что Вы используете, <<< иначе здесь-строка и тот тип перенаправления реализованы через временные файлы, которые являются сразу несвязанными (иначе удаленный). Знание также, что процессы наследовали дескрипторы файлов (и stdin среди них) 1 от родителя до ребенка, когда sudo -S выполняется, это читает свой вход из временного файла, который Ваша исходная оболочка передала ему (тот, который читает sudo -S команда). Вы видите что в действии:

$ sudo -S bash -c 'ls -l /proc/self/fd/0' <<< "mypasswd"
lr-x------ 1 root root 64 Feb 26 13:12 /proc/self/fd/0 -> '/tmp/sh-thd.cUOOXU (deleted)'

Таким образом, nano отчеты Too many errors from stdin ошибка в таком случае. То, что может быть сделано, должно вручную повторно соединить проводом где stdin прибывает из.

$ sudo -S bash -c 'exec < /dev/tty; nano /tmp/foobar' <<< "mypasswd"

$ sudo -S bash -c 'nano /tmp/foobar < /dev/tty' <<< "mypasswd"

Любая из двух команд будет lauch nano правильно и другие команды также. /dev/tty специальный файл, представляющий текущее оконечное устройство, и это - эффективно то же самое как stdin из "нормальной" интерактивной оболочки (и конечно я упрощаю тот оператор).

Другая вариация на тему $ sudo -S bash -c 'nano /tmp/foobar 0>&1' <<<"mypasswd". stdout эффективно точки к тому же оконечному устройству (если Вы явно не обеспечили перенаправление, чтобы иметь точку stdout где-то в другом месте). Таким образом, если мы делаем stdin точка, чтобы быть duplicate из stdout, это - эффективно то же решение как выше. (И если Вы задаетесь вопросом, почему я выделился dup часть, поэтому dup2() syscall является одним ответственным за все манипулирование дескрипторов файлов под капотом),


Внимание

Однако обратите внимание, что я не поощряю использовать sudo -S в интерактивной оболочке, так как пароли останутся в истории оболочки

$ sudo -S bash -c 'sleep 3m' <<< "ohnomypassword"
^C
$ history 2
 2016  sudo -S bash -c 'sleep 3m' <<< "ohnomypassword"
 2017  history 2

sudo -S более подходит для использования с другими процессами, где sudo -S ожидал бы вход через конвейер, идеально от zenity --password или dialog --passwordbox "foobar text" 200 200 (см. extra1 и extra2 о диалоговом окне).


1. Если файл открыт с O_CLOEXEC набор флага, дочерний процесс или замененный процесс, порожденный через execve() тип флага не будет иметь доступа к тому дескриптору файла - который является им, будет замкнут execve()

5
ответ дан 26 October 2019 в 03:55

Другие вопросы по тегам:

Похожие вопросы: