Detailed explanation of initialization mechanism in bash

  • 2021-07-26 09:17:14
  • OfStack

Bash initialization file

Interactive login shell

We can get 1 login shell in the following cases:

The top-level shell obtained when logging in to the system, whether through the local terminal or through the network ssh. The login shell obtained in this case is an interactive shell. You can get an interactive login shell by calling bash with the-login option under the terminal. Calling bash (for example: #!/bin/bash--login) with the--login option in the script yields a non-interactive login shell. Use su-When you switch to a specified user, get the user's ES29shell. If-is not used, non-login shell is obtained.

When login shell starts, it first reads /etc/profile system global configuration, then looks for ~ /.bash_profile, ~ /.bash_login, ~ /.profile configuration files in turn, and reads the first found and readable file.

login shell Read and execute the commands in ~/. bash_logout on exit. If the configuration file exists but is unreadable, an error message will be displayed; If the file does not exist, bash will automatically search for the next file.

By default, global environment variables such as PATH, USER, MAIL, HOSTNAME and HISTSIZE are defined in the/etc/profile file, and the file /etc/bash. bashrc (containing system-level shell functions and aliases) and all *. sh files used to initialize specific programs under the/etc/profile. d path are automatically imported.

Interactive non-login shell

Non-login shell means that you don't have to pass system authentication at startup. The terminal opened by the user in GUI defaults to non-login shell, which can be judged by logout command:


#  In Ubuntu GUI Desktop open 1 Terminals 
> logout
bash: logout: not login shell: use `exit'
> bash --login
> logout #  Logout normally   Nothing will be output 

The non-registered shell only reads the ~ /.bashrc resource file during initialization, while the ~ /.bashrc file is automatically loaded by ~ /.bash_profile or ~/. profile. Therefore, in order to ensure the same configuration of login shell and interactive non-login shell, environment variables are generally defined in the ~ /.bashrc file.


> echo "export sflag=\"login shell will see this message\"" >> ~/.profile  
> bash 
> echo $sflag 
          #  This variable cannot be found   Will print 1 Blank lines 
> exit 
> bash --login 
> echo $sflag 
login shell will see this message 
> logout

Non-interactive shell

When the script is executed through the bash command, shell is started in a non-interactive (non-interactively) manner, which ensures that the script will not be interfered by the user during execution. When the non-interactive script starts, only the file pointed to by the BASH_ENV variable is loaded. Note, however, that since the PATH variable is not loaded by default by non-interactive shell, the value of the variable BASH_ENV should be an absolute path.

With special variables-you can view the current shell mode:


> echo $-
himBHs #  With 'i 'Is interactive shell

Another simple way is to check whether the prompt environment variable PS1 exists in the current shell.


if [ -z "$PS1" ]; then echo " Non-interactive ";else echo " Interactive ";fi

Special circumstances

Compatibility mode

If bash is invoked with the command sh, bash is initialized in the same manner as sh for compatibility. When started as login shell, bash reads the/etc/profile and ~/. profile configuration files in turn. When started as non-login shell, bash only reads the file pointed to by the environment variable ENV.

POSIX Mode

When the bash is started by:

Settings set -o posix Or export POSIXLY_CORRECT=1 bash --posix

bash is initialized as much as possible to the POSIX standard and only reads the files pointed to by the environment variable ENV.

Remote startup script

Only the ~/. bashrc file will be loaded when using the rshd remote startup script, but be careful not to use remote commands such as rlogin, telnet, rsh, rcp as these commands transmit unencrypted plaintext information. Use SSH if you have remote access requirements.

UID does not match EUID

When the process is created, the information required for the process to run is recorded in task_struct. Among them, UID (real user ID) is used to record ID of the user who created the process, EUID (effective user ID) is used to judge the access level of the current process to the file, and UID = EUID in general cases. If the set-user-ID: SUID bit of the executable file is valid (for example:-rwsr-xr-x, the user's x is replaced by s), it means that when the file is executed, the process has the rights of the file owner instead of the permissions of the executor (the value of EUID is ID of the file owner).

If we set the set-user-id flag for the bash executable file, since its default owner is root, when other non-root users run bash, the UID of the process will not be equal to EUID. In this case, for security purposes, bash will not load any files during initialization.

Restricted shell

Startup via rbash or bash--restricted or bash--r generates a functionally limited shell as follows:

You cannot use the cd command and the command cannot contain/ You cannot change the SHELL, PATH, ENV, and BASH_ENV environment variables The parameters of the source command cannot also contain files with/ hash p < path > < name > The parameters of the command used to alias the path cannot include/ Initialization does not import the functions in the file and ignores SHELLOPTS You cannot use redirection You cannot use the exec command You cannot use enable-f/-d to add and delete commands You cannot use command-p to specify the path required to run the command Restriction mode cannot be actively turned off

This functionality can theoretically allow users to execute specified files in specified folders to accomplish limited functionality, but if the environment variables are not set properly, users can easily lift the restrictions:


> rbash
> cd /etc
rbash: cd: restricted
> bash
> cd /etc #  It can be successfully executed, because at this time we are in bash In the environment, there are no restrictions 

An effective way is to limit the commands that new users can execute. For example, we can create a new ruser that can only execute ftp commands:


> useradd -s /bin/rbash ruser #  Set the provided when the user logs in shell
> chown -R root:ruser /home/ruser/.bashrc /home/ruser/.bash_profile
#  Settings root For the owner, ruser Group is the group owner (newly created ruser Default input ruser Group) 
> chmod 640 /home/ruser/.bashrc /home/ruser/.bash_profile
# root Can read and write, ruser Users in the group are read-only, and other users can't do anything 
> mkdir /home/ruser/bin #  Store executable files or links for users 
> echo "export PATH=/home/ruser/bin" >> /home/ruser/.bash_profile
> ln -s /user/bin/ftp /home/ruser/bin/ftp

Related articles: