Возможно ли, чтобы была оболочка входа в систему, которая не была бы интерактивной?

11

При интерпретации этой блок-схемы

введите описание изображения здесь

Я обнаружил, что в человеке Bash:

Когда bash вызывается как интерактивная оболочка входа в систему или как неинтерактивная оболочка с параметром --login, она сначала читает и выполняет команды из файла / etc / profile, если этот файл существует.

Это означает, что интерактивные оболочки входа в систему читаются /etc/profile(без --noprofile)

Также неинтерактивные оболочки с опцией --loginчтения/etc/profile

Это, похоже, оставляет некоторые возможные оболочки входа в систему (в которых $0начинается с a -), которые не являются интерактивными (запустить скрипт, может быть, так же просто, как date), могут не читаться (источник) /etc/profile.

Чтобы подтвердить или опровергнуть эту идею:

Сначала я попытался использовать su -l -, который запускает оболочку входа в систему с -первым символом, но я не могу сделать его неинтерактивным (и не могу представить тесты для его проверки).

Называть что-то вроде

$ bash -c 'date' -bash

Не сообщает, что является оболочкой входа (даже если первый символ - -).

Попробуйте это, чтобы раскрыть детали:

   $ bash -c 'echo "$0 $- ||$(shopt -p login_shell)||";date' -bash
      -bash hBc ||shopt -u login_shell||
      Fri Aug 19 06:32:31 EDT 2016

$0Имеет в -качестве первого символа, не существует i(интерактивный) стоимости , $-но не сообщается , как login_shell(на -u). В этом случае / etc / profile не был прочитан, но я не уверен, что это правильный тест.


В этом ответе также упоминается о «редких неинтерактивных оболочках для входа в систему», которые недостаточно конкретны для этого вопроса.


Заключение этого парня в том , что /etc/profileвсегда читается.

Прочитайте сводную таблицу: прочитаны как интерактивные, так и неинтерактивные оболочки входа /etc/profile


И, если примеры с этой страницы верны:

Some examples

$ su bob                   # interactive non-login shell
$ su - bob                 # interactive login shell
$ exec su - bob            # interactive login shell
$ exec su - bob -c 'env'   # non-interactive login shell
$ ssh bob@example.com      # interactive login shell, `~/.profile`
$ ssh bob@example.com env  # non-interactive non-login shell, `~/.bashrc`

Тест exec su - bob -c 'env'отчетов, которые /etc/profileбыли прочитаны.


Короче говоря:

Возможно ли иметь неинтерактивную оболочку входа в систему (не вызывается с --login или -l)?

И если правда, это чтение /etc/profileфайла?

Если вышеприведенное верно, мы должны сделать вывод, что ВСЕ оболочки входа [интерактивные (или нет)] читают / etc / profile (без --noprofileопции).

Примечание: чтобы обнаружить, что / etc / profile читается, просто добавьте в самом начале файла эту команду:

echo "'/etc/profile' is being read"
Сообщество
источник

Ответы:

2

Неинтерактивная оболочка входа в систему необычна, но возможна. Если вы запускаете оболочку с нулевым аргументом (обычно это имя исполняемого файла), для которого задана строка, начинающаяся с a -, это оболочка входа, независимо от того, интерактивна она или нет.

$ ln -s /bin/bash ./-bash
$ echo 'shopt -p login_shell; echo $-' | HOME=/none PATH=.:$PATH -bash
shopt -s login_shell
hB

Ваша попытка bash -c date -bashне сработала, потому что это не говорит о том, что оболочка является оболочкой входа в систему: нулевой аргумент - bashнет -bash. После начала Баша, она устанавливает переменную $0в -bashвместо нулевого аргумента, но нулевой аргумент это то , что имеет значение.

Вы можете запустить неинтерактивную оболочку входа в систему с помощью su -lили su -, но вам нужно организовать стандартный ввод, чтобы он не был терминалом, но при этом иметь возможность авторизации (без необходимости вводить пароль или согласовывать пароль в начале вход). С sudo: run может быть проще sudo trueполучить учетные данные о присутствии, тогда как учетные данные все еще действительны echo 'shopt -p login_shell; echo $-' | sudo -i.

См. Также Разница между Оболочкой входа в систему и Оболочкой без регистрации?

Жиль "ТАК - перестань быть злым"
источник
4

Я видел графические среды входа в систему, которые делают:

exec "$SHELL" -l -c 'exec start-window-or-session-manager'

или эквивалент:

exec -a "-$SHELL" "$SHELL" <<EOF
exec start-window-or-session-manager
EOF

Таким образом, файл инициализации сеанса (например, ~/.profileдля оболочек типа Bourne (и соответствующих /etcдля некоторых)) должен быть прочитан и применен.

Первый не работает со всеми оболочками. -lподдерживается большим количеством оболочек, но не всеми, а на некоторых, вроде csh/ tcsh, не может использоваться с -c. Впрочем, первый символ argv[0]бытия -понимается всеми оболочками, поскольку именно он loginсообщает оболочкам, что они являются оболочками входа в систему.

Во втором случае stdin этой оболочки - это нечто иное, чем ttyустройство ( <<реализуется временным обычным файлом или каналом в зависимости от оболочки), поэтому оболочка не является интерактивной (определение интерактивного существа при взаимодействии человека). с этим).

Стефан Шазелас
источник
Первый использует --loginопцию. Во-вторых, если я exec -a "-bash" "bash" <<<"shopt -p login_shell; echo $0 $-"получу (закодирован в C qoutes) $'/etc/profile read\nshopt -s login_shell\nbash himBH', это логин, но он интерактивный. Нам нужен логин и неинтерактивность . Что мне не хватает?
@sorontar, with <<<"$-", который $-расширяется вызывающей оболочкой из-за двойных кавычек. Вызываемая оболочка не является интерактивной, потому что ее стандартный ввод не является tty.
Стефан Шазелас
Ах, да, вы правы, сэр. Однако, исправив ошибку, мы можем сделать это: exec -a "-bash" "bash" <<\EOF shopt -p login_shell; echo $0 $- EOFчтобы получить это подтверждение: $'/etc/profile read stdin: is not a tty shopt -s login_shell -bash hB'так что, да, возможна неинтерактивная оболочка входа в систему, и она все еще читается /etc/profile. Должны ли мы сделать вывод, что ВСЕ оболочки входа в систему читаются /etc/profile?
ksh ясно дает понять, что это неинтерактивная оболочка для входа , попробуйте exec -a "-ksh" "ksh" <<\EOF echo $0; set -o EOF:).
1
@sorontar, я думаю, вы можете ожидать, что большинство реализаций оболочки будут читать свои файлы инициализации сеанса при вызове в качестве оболочек входа в систему. То, чем они являются, зависит от реализации и версии оболочки. В случае bashс обработкой стартового файла IMO довольно запутан, вы обнаружите, что некоторые системы исправили его для более разумного поведения, добавив еще больше вариаций.
Стефан Шазелас
3

Да, возможны неинтерактивные логины

$ head -1 /etc/profile
echo PROFILE BEING READ

$ echo echo hello | su -
PROFILE BEING READ
stdin: is not a tty
hello

$
Стивен Харрис
источник
Это похоже на это упрощенное su -c 'echo hello' -. Который, чтобы проверить то , что нам нужно, следует записать так: su -c 'echo $0 $-; shopt -p login_shell' -чтобы получить этот ответ , подтверждающий (закодированный в кавычках C): $'/etc/profile read \n -su hBc \n shopt -s login_shell'. Это подтверждает, что неинтерактивная оболочка входа в систему была оправдана и что в процессе была прочитана / etc / profile. Спасибо.
0

Возможно ли иметь неинтерактивную оболочку входа в систему (не вызывается с --login или -l)?

ДА.

$ (exec -a '-' bash -c 'shopt -q login_shell && echo login shell')

Однако обратите внимание, /etc/profileчто не будет использоваться для неинтерактивной оболочки входа в систему, если --loginне указан аргумент.

Распространенная идиома, которая вызывает неинтерактивную оболочку входа в систему:

$ su - someuser -c somecommand

Но страдает тот факт, что /etc/profileне выполняется.

Это поведение можно изменить, но оно включает в себя настройку исходного кода Bash во время компиляции, раскомментировав параметр, найденный в config-top.h :

/* Define this to make non-interactive shells begun with argv[0][0] == '-'
run the startup files when not in posix mode. */
/* #define NON_INTERACTIVE_LOGIN_SHELLS */

Когда я исследовал эту suаномалию , я обнаружил, что другие оболочки, в том числе zshи dashне имеют этого несоответствия.

starfry
источник