The Bash Scripting bash scripting and basic configuration file

Script basics

References: Shell Scripts (Bash Reference Manual)

Loosely speaking, a programming language based on the way the code is running, can be divided into two ways:

  • Compile and run: The program needs to be compiled into a binary file that can be run first human machine recognizable code files before running. For example, and Java language.
  • Run interpretation: the need for a programming language interpreter, read the code file is run by an interpreter and run. Such as language (interpreter: / usr / bin / python) and a shell script (interpreter: / bin / bash).

According to another application on whether to call the OS to points:

  • Scripting languages ​​(shell script): bash itself dependent on the OS and other applications (for example: grep / sed / awk, etc.).
  • Complete programming languages: rely on their own grammar and its own rich library file to complete the task, dependent on the system is low, such as python, PHP and so on.

According to the programming model:

  • Process formula: instruction code to organize the center, to the data service code. Like C language and bash.
  • Object of formula: Center to organize the code, instructions about the data organization data. The process is generally programmed to create the class (class, for example: a human), in accordance with an instance of the class object (e.g.: Aaron brother), an object class having common properties (e.g., humans hands and feet, then there Aaron brother) objects can have their own methods (method, such as a blog). Like the Java language.

Like C ++ and python are supported by both object-oriented and process-oriented support.

Therefore, we can conclude: bash is running an explanation of procedural scripting language, and bash script is a program on the command of its own programming logic and OS piled up pending file.

In the shell script, the first line we need to communicate our core script what kind of interpreter (interpreter) to explain the use of run. Shaped like:

#! / bin / SH 
or 
# ! / bin / bash 
or 
# ! / usr / bin / Python

"#!" Is fixed format, called shebang or hashbang, follow the path followed by the interpreter program. If / bin / bash bash script that is, if it is / usr / bin / python that is the python script.

shebang can add options such as a login shell script can make the formula (login) at the time of execution.

#!/bin/bash -l

bash script file extension (also known as extensions) is generally ".sh", this name mainly for people easy to identify with, what specific script interpreter during execution, regardless of the file extension.

The script also need to have execute permissions. When executed, it is necessary to use a relative path or absolute path before they execute correctly.

~]# cat alongdidi.sh
#!/bin/bash
...
~]# chmod a+x alongdidi.sh
~]# ./alongdidi.sh
~]# /PATH/TO/alongdidi.sh

If you simply type the name of the script to execute, then, bash will look for alongdidi.sh command from the built-in commands, such as PATH, if our script does not exist in the current path PATH, will give an error.

~]# alongdidi.sh
bash: alongdidi.sh: command not found...

Scripts can no shebang and execute permissions, we still can order by calling the bash, bash script as a parameter to perform, this is also possible.

~]# bash alongdidi.sh

There is a blank line in the script will be ignored, bash will not print out blank lines.

In addition shebang (#!) This special format, the # rest position, its subsequent characters will be considered as a script comment.

Bash execute a script, in fact, create a sub-shell in the current shell to execute.

Profiles

Whether we through physical devices (mouse, keyboard and monitor) to the physical servers / machines, we also connected to the Linux server through the SSH client (either GUI or CLI). The system will enable a bash on the terminal we connect, we interact with the OS through the shell to.

Even if we execute bash script, the system will create a sub-bash to complete the task.

The bash at boot time, you need to read its configuration files, the official also called it boot files (startup files). Bash for reading these files at startup and execution of an instruction set which bash environment.

Interactive and logon type

Bash need to determine whether it has an interactive (interactive) logon type and characteristics (login) to determine which configuration files they should read.

There are two methods is determined whether an interactive shell:

A method of: determining the special variable "$ -" contains the letter i. There are other special variables bash, interested, please refer to Special the Parameters (Bash Reference Manual) .

[root@c7-server ~]# echo $-
himBH
[root@c7-server ~]# cat alongdidi.sh 
#!/bin/bash
echo $-
[root@c7-server ~]# bash alongdidi.sh
hB

Method two: whether the variable "$ PS1" is empty. Interactive logon will set this variable, if the variable is empty, compared to non-interactive, or interactive. PS1 is Prompt String, String prompt means, it belongs to the official website of the variables of the Bourne Shell one.

[root@c7-server ~]# echo $PS1
[\u@\h \W]\$
[root@c7-server ~]# cat alongdidi.sh 
#!/bin/bash
echo $PS1
[root@c7-server ~]# bash alongdidi.sh

[root@c7-server ~]#

Determine whether the login shell type, use the bash built-in command shopt to see. With its built-in command set and are used to modify the behavior of the shell. Modifying Shell Behavior (Bash Reference Manual)

[root@c7-server ~]# shopt login_shell 
login_shell        on
[root@c7-server ~]# cat alongdidi.sh 
#!/bin/bash
shopt login_shell
[root@c7-server ~]# bash alongdidi.sh
login_shell        off
[root@c7-server ~]# bash
[root@c7-server ~]# shopt login_shell 
login_shell        off

Common bash startup mode

PS: Finally, also Windows to the black for a moment. Really feeling windows should not be considered a multi-user, maintaining the previous Windows Server when using a remote connection can only connect the user with super pipe 2 or 3 only, more to die. Currently I do not know why, may limit their windows so.

1, SSH login protocol by Xshell clients.

Pseudo-terminal. An interactive, logon type.

[root@c7-server ~]# tty
/dev/pts/1
[root@c7-server ~]# who am i
root     pts/1        2019-12-12 15:39 (192.168.152.1)
[root@c7-server ~]# echo $PS1; shopt login_shell 
[\u@\h \W]\$
login_shell        on

2, right-click on the desktop of the terminal is opened in a graphical interface.

 Pseudo-terminal. Interactive, non-login style.

[root@c7-server ~]# tty
/dev/pts/0
[root@c7-server ~]# who am i
root     pts/0        2019-12-12 15:28 (:0)
[root@c7-server ~]# echo $PS1; shopt login_shell 
[\u@\h \W]\$
login_shell        off

By setting the property that it becomes the terminal to log in the formula.

 

3, virtual terminal.

Switched by Ctrl + Alt + Fn, n is a positive integer, the theme is located Ctrl + Alt + F2, this is called virtual terminal. An interactive, logon type.

 

4, su command to start the bash.

Do not use su login options. Interactive, non-login style.

[root@c7-server ~]# su root
[root@c7-server ~]# echo $PS1; shopt login_shell 
[\u@\h \W]\$
login_shell        off

Use su login options. An interactive, logon type.

-, -l, --login: the shell is a login shell.

[root@c7-server ~]# su - root
Last login: Thu Dec 12 16:10:36 CST 2019 on pts/1
[root@c7-server ~]# echo $PS1; shopt login_shell 
[\u@\h \W]\$
login_shell        on

5, activated by the sub-bash command shell.

Certain interactive, whether the login type to see whether the -l option.

[root@c7-server ~]# echo $PS1; shopt login_shell 
[\u@\h \W]\$
login_shell        off
[root@c7-server ~]# exit
exit
[root@c7-server ~]# bash -l
[root@c7-server ~]# echo $PS1; shopt login_shell 
[\u@\h \W]\$
login_shell        on

6, command combination.

PS: This part can not read, from horse dragon.

In this case, the interactive logon type situation inherited from the parent shell.

[root@c7-server ~]# (echo $BASH_SUBSHELL; echo $PS1; shopt login_shell)
1
[\u@\h \W]\$
login_shell        on
[root@c7-server ~]# su
[root@c7-server ~]# (echo $BASH_SUBSHELL; echo $PS1; shopt login_shell)
1
[\u@\h \W]\$
login_shell        off

7, remote command execution using the ssh command.

Non-interactive, non-login style. In this way, the official website is called remote shell, Remote Shell Daemon.

[root@c7-server ~]# ssh localhost 'echo $PS1; shopt login_shell'
root@localhost's password: 

login_shell        off

8, run shell scripts.

Run by bash command. Non-interactive, depending on whether the type is logged with the -l option.

[root@c7-server ~]# cat alongdidi.sh
#!/bin/bash
echo $PS1
shopt login_shell
[root@c7-server ~]# bash alongdidi.sh

login_shell        off
[root@c7-server ~]# bash -l alongdidi.sh

login_shell        on

After the file has run directly execute permissions. Non-interactive, non-login style.

[root@c7-server ~]# ./alongdidi.sh 

login_shell        off

If shebang with the -l option, then directly run non-interactive, logon type.

do not bash through with the -l option, still non-interactive, non-login style.

That is, whether to log type, look at whether the CLI bash with the -l option, look at whether shebang with the -l option. They are non-interactive.

[root@c7-server ~]# cat alongdidi.sh 
#!/bin/bash -l
echo $PS1
shopt login_shell
[root@c7-server ~]# ./alongdidi.sh 

login_shell        on
[root@c7-server ~]# bash alongdidi.sh 

login_shell        off

 

Loading profile

In bash, load the configuration file is achieved by way of a read command, they bash built-in command source and. "."

source filename [arguments]
. filename [arguments]

Note that there is a single decimal point, it is a bash built-in command. If there are arguments, then position it as a parameter.

Essentially read the file and the file command in the current shell. (Execute a shell script is different from the need to create a sub-shell)

bash relevant configuration file, there are these:

/etc/profile
~/.bash_profile
~/.bashrc
/etc/bashrc
/etc/profile.d/*.sh

Note: These profiles are generally required to have permission to read the job (although it may not matter for the root user)

Located in the configuration file in the user's home directory for the user's private profile, only the corresponding user will be loaded, customized for the user can be realized. Configuration file located in the / etc / directory, configuration files can be understood as a global force for all users.

In order to test different scenarios which bash startup files are loaded, we have these documents at the end of the plus one echo statement. Note that we are at the end of the echo statement added files, execute bash script is executed in order from top to bottom, the position is critical.

echo "echo '/etc/profile goes'" >>/etc/profile
echo "echo '~/.bash_profile goes'" >>~/.bash_profile
echo "echo '~/.bashrc goes'" >>~/.bashrc
echo "echo '/etc/bashrc goes'" >>/etc/bashrc
echo "echo '/etc/profile.d/test.sh goes'" >>/etc/profile.d/test.sh

1, as long as the bash login type (whether or not interactive): first read / etc / profile, and then click Search ~ / .bash_profile, ~ / .bash_login and ~ / .profile and load only the first search and readable file. When bash exit, read ~ / .bash_logout.

In the / etc / profile file, a reader command:

for i in /etc/profile.d/*.sh /etc/profile.d/sh.local ; do
    if [ -r "$i" ]; then
        if [ "${-#*i}" != "$-" ]; then
            . "$i"
        else
            . "$i" >/dev/null
        fi
    fi
done

* .Sh sh.local and determines whether the file is readable /etc/profile.d/ directory exists, if so, is read. Judgment in bold red, is to determine whether the interactive bash, and if so when reading the output configuration file STDOUT, or do not output.

No /etc/profile.d/sh.local file in CentOS 6, the instruction file is not loaded. On CentOS 7, this file is only one line comments, In my broken English level, I guess it should be used to fill in some environment variables can be used to overwrite / etc / profile environment variables.

~]# cat /etc/profile.d/sh.local
#Add any required envvar overrides to this file, it is sourced from /etc/profile

For root, because the presence of ~ / .bash_profile file and read (in my test environment, ordinary users provided with a readable ~ / .bash_profile), so ~ / .bash_login and ~ / .profile was ignored.

In ~ / .bash_profile, there reading instruction:

PS: I remember watching that part of English comments.

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

In ~ / .bashrc, there are a read instruction:

# Source global definitions
if [ -f /etc/bashrc ]; then
        . /etc/bashrc
fi

In the / etc / bashrc, although there reading instruction, but this part of the instruction is only executed in the case where the non-logged formula:

if ! shopt -q login_shell ; then # We're not a login shell
...
    for i in /etc/profile.d/*.sh; do
        if [ -r "$i" ]; then
            if [ "$PS1" ]; then
                . "$i"
            else
                . "$i" >/dev/null
            fi
        fi
    done
...
fi

Illustrated as follows. In numerical order, the first loaded first, second reloading finished loading.

 

 

We tested several of the earlier scenes start to look at bash. Note that you must have a login type of job. Because this section we discuss the login style.

I. Xshell client, pseudo-terminal login, type interactive logon.

/etc/profile.d/test.sh goes
/etc/profile goes
/etc/bashrc goes
~/.bashrc goes
~/.bash_profile goes

The reason why after loading the first show, it is because we echo statement is added to the end of the script, and read the subsequent configuration file is in the middle section of the script.

II. Ssh remote login. Interactive logon type.

[root@c7-server ~]# ssh localhost
root@localhost's password: 
Last login: Fri Dec 13 16:01:43 2019 from 192.168.152.1
/etc/profile.d/test.sh goes
/etc/profile goes
/etc/bashrc goes
~/.bashrc goes
~/.bash_profile goes

III. Promoter shell with the login options.

~]# bash -l
/etc/profile.d/test.sh goes
/etc/profile goes
/etc/bashrc goes
~/.bashrc goes
~/.bash_profile goes

IV. Login type switch users.

~]# su -l
Last login: Fri Dec 13 16:03:20 CST 2019 from localhost on pts/3
/etc/profile.d/test.sh goes
/etc/profile goes
/etc/bashrc goes
~/.bashrc goes
~/.bash_profile goes

V. When executing the script with login options.

[root@c7-server ~]# cat a.sh 
#!/bin/bash -l
echo 'haha'
[root@c7-server ~]# ./a.sh 
/etc/profile goes
/etc/bashrc goes
~/.bashrc goes
~/.bash_profile goes
haha
[root@c7-server ~]# bash -l a.sh 
/etc/profile goes
/etc/bashrc goes
~/.bashrc goes
~/.bash_profile goes
haha

Execution of the script is non-interactive, but when reading /etc/profile.d/*.sh files in non-interactive scenes, there will be no output. (Defined in the / etc / profile file, you may be turned on to see)

. "$i" >/dev/null 2>&1

Therefore, it will not output:

/etc/profile.d/test.sh goes

Note that just does not output only, but there are still loaded configuration file, if such set environment variables involved, etc., will still perform.

2, but non-login interactive style bash: read ~ / .bashrc file, without reading /etc/profile,~/.bash_profile,~/.bash_login and ~ / .profile.

 

Corresponding to the scene with no login option to create a sub-bash or su user switching.

[root@c7-server ~]# bash
/etc/profile.d/test.sh goes
/etc/bashrc goes
~/.bashrc goes
[root@c7-server ~]# su
/etc/profile.d/test.sh goes
/etc/bashrc goes
~/.bashrc goes

3, non-interactive non-login-style bash.

Without loading any configuration file, try to expand the environment variable BASH_ENV (This variable is typically stored in a certain path to a configuration file), if the value of the corresponding load profiles, behavior is as follows:

if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi

Normal in the preparation and execution bash script, will not deliberately add login options, so do almost all of the bash script is of this type.

There is a non-interactive non-login bash type of special case, do not use this configuration file loading. Look at an example.

4, non-interactive non-login bash type of exception: remote shell (Remote Shell Daemon).

Loading embodiment as shown in FIG.

 

Since the non-log type shell, and therefore does not output the read * .sh time.

[root@c7-server ~]# ssh localhost echo 'Remote Shell Daemon'
root@localhost's password: 
/etc/bashrc goes
~/.bashrc goes
Remote Shell Daemon

Guess you like

Origin www.linuxidc.com/Linux/2020-01/161941.htm
Recommended