Home > Software engineering >  What is the difference between exit and break in a login shell
What is the difference between exit and break in a login shell

Time:07-06

I would like to understand why exit behaves differently than break in the following command:

$ set -o pipefail; true | bash -e -lxc 'while true; do <BREAK/EXIT>; done'; echo $?

Is this a bug? Because depending on which one is used, the ~./bash_logout is called throwing an exit code 1 (because clear_console -q fails).

  • With break -> exit code 0
$ set -o pipefail; true | bash -e -lxc 'while true; do break; done'; echo $?
  '[' '' ']'
  '[' -d /etc/profile.d ']'
  for i in /etc/profile.d/*.sh
  '[' -r /etc/profile.d/01-locale-fix.sh ']'
  . /etc/profile.d/01-locale-fix.sh
    /usr/bin/locale-check C.UTF-8
   eval
  for i in /etc/profile.d/*.sh
  '[' -r /etc/profile.d/apps-bin-path.sh ']'
  . /etc/profile.d/apps-bin-path.sh
   snap_bin_path=/snap/bin
   '[' -n '' ']'
   '[' -z /usr/share/gnome:/usr/local/share:/usr/share:/var/lib/snapd/desktop ']'
   snap_xdg_path=/var/lib/snapd/desktop
   '[' -n '' ']'
  for i in /etc/profile.d/*.sh
  '[' -r /etc/profile.d/bash_completion.sh ']'
  . /etc/profile.d/bash_completion.sh
   '[' 'x5.1.16(1)-release' '!=' x -a x '!=' x -a x = x ']'
  for i in /etc/profile.d/*.sh
  '[' -r /etc/profile.d/cedilla-portuguese.sh ']'
  . /etc/profile.d/cedilla-portuguese.sh
   '[' nl = pt -a en '!=' pt ']'
  for i in /etc/profile.d/*.sh
  '[' -r /etc/profile.d/debuginfod.sh ']'
  for i in /etc/profile.d/*.sh
  '[' -r /etc/profile.d/gnome-session_gnomerc.sh ']'
  . /etc/profile.d/gnome-session_gnomerc.sh
   '[' tty = wayland ']'
   '[' -z /usr/share/gnome:/usr/local/share:/usr/share:/var/lib/snapd/desktop ']'
   '[' -n '' ']'
   export XDG_DATA_DIRS
  for i in /etc/profile.d/*.sh
  '[' -r /etc/profile.d/im-config_wayland.sh ']'
  . /etc/profile.d/im-config_wayland.sh
   '[' tty '!=' wayland ']'
   return
  for i in /etc/profile.d/*.sh
  '[' -r /etc/profile.d/vte-2.91.sh ']'
  . /etc/profile.d/vte-2.91.sh
   '[' -n '5.1.16(1)-release' -o -n '' ']'
   [[ ehxBc == *i* ]]
   return 0
  for i in /etc/profile.d/*.sh
  '[' -r /etc/profile.d/xdg_dirs_desktop_session.sh ']'
  . /etc/profile.d/xdg_dirs_desktop_session.sh
   DEFAULT_XDG_CONFIG_DIRS=/etc/xdg
   DEFAULT_XDG_DATA_DIRS=/usr/local/share/:/usr/share/
   '[' -n '' ']'
  unset i
  '[' -n '5.1.16(1)-release' ']'
  '[' -f /home/user/.bashrc ']'
  . /home/user/.bashrc
   case $- in
   return
  '[' -d /home/user/bin ']'
  '[' -d /home/user/.local/bin ']'
  true
  break
0
  • With exit -> exit code 1
$ set -o pipefail; true | bash -e -lxc 'while true; do exit; done'; echo $?
  '[' '' ']'
  '[' -d /etc/profile.d ']'
  for i in /etc/profile.d/*.sh
  '[' -r /etc/profile.d/01-locale-fix.sh ']'
  . /etc/profile.d/01-locale-fix.sh
    /usr/bin/locale-check C.UTF-8
   eval
  for i in /etc/profile.d/*.sh
  '[' -r /etc/profile.d/apps-bin-path.sh ']'
  . /etc/profile.d/apps-bin-path.sh
   snap_bin_path=/snap/bin
   '[' -n '' ']'
   '[' -z /usr/share/gnome:/usr/local/share:/usr/share:/var/lib/snapd/desktop ']'
   snap_xdg_path=/var/lib/snapd/desktop
   '[' -n '' ']'
  for i in /etc/profile.d/*.sh
  '[' -r /etc/profile.d/bash_completion.sh ']'
  . /etc/profile.d/bash_completion.sh
   '[' 'x5.1.16(1)-release' '!=' x -a x '!=' x -a x = x ']'
  for i in /etc/profile.d/*.sh
  '[' -r /etc/profile.d/cedilla-portuguese.sh ']'
  . /etc/profile.d/cedilla-portuguese.sh
   '[' nl = pt -a en '!=' pt ']'
  for i in /etc/profile.d/*.sh
  '[' -r /etc/profile.d/debuginfod.sh ']'
  for i in /etc/profile.d/*.sh
  '[' -r /etc/profile.d/gnome-session_gnomerc.sh ']'
  . /etc/profile.d/gnome-session_gnomerc.sh
   '[' tty = wayland ']'
   '[' -z /usr/share/gnome:/usr/local/share:/usr/share:/var/lib/snapd/desktop ']'
   '[' -n '' ']'
   export XDG_DATA_DIRS
  for i in /etc/profile.d/*.sh
  '[' -r /etc/profile.d/im-config_wayland.sh ']'
  . /etc/profile.d/im-config_wayland.sh
   '[' tty '!=' wayland ']'
   return
  for i in /etc/profile.d/*.sh
  '[' -r /etc/profile.d/vte-2.91.sh ']'
  . /etc/profile.d/vte-2.91.sh
   '[' -n '5.1.16(1)-release' -o -n '' ']'
   [[ ehxBc == *i* ]]
   return 0
  for i in /etc/profile.d/*.sh
  '[' -r /etc/profile.d/xdg_dirs_desktop_session.sh ']'
  . /etc/profile.d/xdg_dirs_desktop_session.sh
   DEFAULT_XDG_CONFIG_DIRS=/etc/xdg
   DEFAULT_XDG_DATA_DIRS=/usr/local/share/:/usr/share/
   '[' -n '' ']'
  unset i
  '[' -n '5.1.16(1)-release' ']'
  '[' -f /home/user/.bashrc ']'
  . /home/user/.bashrc
   case $- in
   return
  '[' -d /home/user/bin ']'
  '[' -d /home/user/.local/bin ']'
  true
  exit
   '[' 1 = 1 ']'
   '[' -x /usr/bin/clear_console ']'
   /usr/bin/clear_console -q
1

CodePudding user response:

What is the difference between exit and break in a login shell

In this case, the difference is in the execution of .bash_logout script. It is not executed when non-interactive login shell exits... on it's own. It is executed when non-interactive login shell calls exit explicitly.

When an interactive login shell exits, or a non-interactive login shell executes the exit builtin command, Bash reads and executes commands from the file ~/.bash_logout, if it exists.

  • Related