Чи можлива наявність оболонки для входу, яка не є інтерактивною?


11

Інтерпретуючи цю блок-схему

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

Я виявив, що в man bash:

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

Це говорить про те, що інтерактивні оболонки входу читають /etc/profile(без --noprofile)

Також неінтерактивні оболонки з можливістю --loginзчитування/etc/profile

Це, здається, залишає деякі можливі оболонки входу (в яких $0починається з а -), які неінтерактивні (запустіть сценарій, можливо, настільки ж просто date), як не можна читати (джерело) /etc/profile.

Щоб підтвердити або спростувати цю ідею:

Спершу я спробував використати su -l -, яка запускає оболонку входу з -першим символом, але я не можу зробити її неінтерактивною (і зможу представити тести, щоб перевірити її).

Викликати щось на кшталт

$ bash -c 'date' -bash

Не повідомляється про оболонку входу (навіть якщо перший символ є a -).

Спробуйте це, щоб розкрити деталь:

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

Значення $0a має -як перший символ, немає значення i(інтерактивне) значення, $-але воно не повідомляється як login_shell(-u). У цьому випадку / etc / профіль не був прочитаний, але я не впевнений, що це правильний тест.


Існує також згадка про «рідкісних неінтерактивний оболонок входу в систему » в цій відповіді , не будучи достатньо конкретним для цього питання.


Висновок цього хлопця в тому , що /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файл?

Якщо вищезазначене вірно, ми маємо зробити висновок, що ВСІ оболонки входу [інтерактивні (чи ні)] читання / тощо / профіль (без --noprofileопції).

Примітка: щоб виявити, що / etc / профіль читається, просто додайте на самому початку файлу цю команду:

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 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для оболонок, подібних до Борна (і відповідних /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, з <<<"$-", що $-розширюється на оболонку виклику через подвійні лапки. Викликана оболонка не є інтерактивною, оскільки її stdin не є 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не мають такої невідповідності.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.