Почему мы не видим ни одного дефиса из $0 в оболочке входа, вызванной с опцией `--login`?

Почему мы не видим ни одного дефиса из $0 в оболочке входа, вызванной с опцией `--login`?

man bashговорит,

 A login shell is one whose first character of argument zero is a -,  or
 one started with the --login option.

Когда мы вызываем терминал, например, mintty -в Cygwin, мы видим один дефис ( -) от $0.

$ echo $0
-bash

Но если мы вызовем оболочку входа с --loginопцией, мы не увидим -.

$bash --login
$echo $0
bash

У меня есть вопросы:

  1. Какова роль -? Хотя мы не можем увидеть его при вызове оболочки входа --login, мы можем проверить тип оболочки, просто запросив соответствующие параметры оболочки, например shopt -q login_shell. Для чего он?

  2. Если роль важна -, почему мы не видим ее в оболочке входа, вызываемой с помощью --login?

  3. Как можно вручную вызвать оболочку входа, нулевой аргумент которой начинается с -?

  4. Это касается и других оболочек, таких как zsh, csh?

решение1

Начальный тире в имени процесса (в argv[0], если быть точным) помещается туда процессом, который вызывает оболочку — loginили какой-то эквивалент. Он сообщает программе оболочки, что она должна действовать как оболочка входа (читай .profileи т. д.). Программа оболочки может выбрать работу в качестве оболочки входа в других обстоятельствах (например, bash и zsh действуют как оболочка входа, если передан -lпараметр командной строки).

Чтобы ответить на ваши вопросы:

  1. Роль -заключается в том, чтобы сообщить оболочке, что она должна вести себя как оболочка входа. Для bash передача --loginв командной строке эквивалентна.
  2. Вы можете увидетьроль-на bash, вызванном с --loginопцией — он читает ~/.profileи т. д. Вы не можете увидеть, -bashбыл ли bash вызван как bash --login, а не -bashпотому, что bash не был вызван как -bash.
  3. Типичные оболочки не позволяют вам выбирать нулевой аргумент, это должно быть имя команды. С zsh вы можете сделать ARGV0=-bash bashи с ksh93, bashили zsh, вы можете сделать (exec -a -bash bash). В mkshили zsh, вы можете сделать hash -- -bash=/bin/bash; -bash. Вы не можете сделать что-то вроде , ln -s /bin/bash ./-bash; ./-bashтак как это целое argv[0]должно начинаться с -. Вы могли бы сделать PATH=:$PATH; -bash, но тогда это имеет этот неприятный побочный эффект добавления ""перед $PATH.
  4. Да.

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

решение2

Вопрос 1 и 2

В дополнение к man bashтому, что вы указали в своем вопросе, на странице руководства сказано:или. Таким образом, у вас есть два способа запустить оболочку входа:

  • Первый символ аргумента ноль — это -.
  • началось с опции --login.

и два пути независимы друг от друга. Оболочка, первый символ аргумента ноль которой является- долженбыть оболочкой входа. Но оболочка, первый символ аргумента которой ноль не является -still, может быть оболочкой входа или нет. Она является оболочкой входа при вызове с помощью --login.

Еще один способ проверить оболочку входа:

$ cuonglm at ~
$ bash --login
$ cuonglm at ~
$ grep -- -l /proc/$$/cmdline
Binary file /proc/7620/cmdline matches

Вопрос 3

Простой способ:

$ cuonglm at ~
$ sudo su -
% root at ~
% shopt -q login_shell && echo "Login shell" || echo "Not login shell"
Login shell

Вопрос 4

Насколько мне известно, zshи в этом случае cshто же самое bash.

Связанный контент