The bash command set

setBash script command is an important part, but often overlooked, leading to the safety of the script and maintainability problems. This article describes its basic usage, so you can feel more comfortable using a Bash script.

I. Introduction

We know that when Bash script execution, it will create a new Shell.


$ bash script.sh

The above code, script.shis performed in which a new Shell. The Shell is the execution environment of the script, Bash default given the various parameters of the environment.

setCommand to change the operating parameters of the Shell environment, that is, you can customize the environment. There are more than a dozen parameters can be customized, the official manual has a complete list, this article describes the most common of four.

By the way, if without any command line parameters, run directly set, it will show all the environmental variables and the Shell function.


$ set

Two, set -u

When executing the script, if you encounter a variable that does not exist, Bash default ignore it.


#!/usr/bin/env bash

echo $a
echo bar

The above code, $ais a variable does not exist. Execution results are as follows.


$ bash script.sh

bar

You can see, echo $athe output of a blank line, Bash ignores that does not exist $a, then continue echo bar. In most cases, this is not the behavior of a developer wants encountered variable does not exist, the script should error, rather than silently down the execution.

set -uIt is used to change this behavior. Coupled with its head in the script, encounters a variable that does not exist would be an error, and stop the execution.


#!/usr/bin/env bash
set -u

echo $a echo bar 

Results are as follows.


$ bash script.sh
bash: script.sh:行4: a: 未绑定的变量 

We can see, the script error, and no longer perform the statements that follow.

-uThere is another way -o nounset, they are equivalent.


set -o nounset

Three, set -x

By default, the script is executed, the screen only displays the results of running, nothing else. If you execute multiple commands in a row, their operating results will be continuous output. Sometimes hard to tell, what a piece of content is generated by the command.

set -xBefore running for the result, the first output of the line command execution.


#!/usr/bin/env bash
set -x

echo bar

Implementation of the above script with the following results.


$ bash script.sh
+ echo bar
bar

It can be seen perform echo barbefore, the command prints out the first line to +represent. This is for debugging complex scripts are very useful.

-xThere is another way -o xtrace.


set -o xtrace

Four, Bash error handling

If the script which has failed to run the command (return value of non-0), Bash default will continue to execute subsequent commands.


#!/usr/bin/env bash

foo
echo bar

The above script, foois a non-existent command will complain when executed. However, Bash will ignore this error and continue down the implementation.


$ bash script.sh
script.sh:行3: foo: 未找到命令 bar 

We can see, Bash just display an error, and not terminated.

This behavior is not conducive to safety and debug scripts. The actual development, if a command fails, it often requires a script to stop execution, to prevent accumulation of error. In this case, using the following general wording.


command || exit 1

The above wording that as long as commandthere is a non-zero return value, the script will stop executing.

If a plurality of operations required to complete before the execution is stopped, it is necessary using three writing below.


# 写法一
command || { echo "command failed"; exit 1; } # 写法二 if ! command; then echo "command failed"; exit 1; fi # 写法三 command if [ "$?" -ne 0 ]; then echo "command failed"; exit 1; fi 

In addition to stop the execution, there is a situation. If there are two commands inheritance, only the first command is successful, before proceeding to the second command, then we must use the following wording.


command1 && command2

Five, set -e

The above wording is somewhat cumbersome, easy to neglect. set -eSolved this problem fundamentally, it makes the script as long as an error occurs, it is terminated.


#!/usr/bin/env bash
set -e

foo
echo bar

Execution results are as follows.


$ bash script.sh
script.sh:行4: foo: 未找到命令 

You can see, the fourth row after execution fails, the script is terminated executed.

set -eThe return value to judge whether a command fails. However, some non-zero return value of the command may not indicate failure, or in the case of developers want to command fails, the script continue execution. Then you can temporarily turn off set -eafter the end of the command execution, and then re-open set -e.


set +e
command1
command2
set -e

The above code, set +emeans closed -eoption set -erepresents reopen -eoption.

Another method is to use command || trueso that even if the command execution fails, the script will not be terminated.


#!/bin/bash
set -e

foo || true echo bar 

The above code, truemaking this line statement is always executed successfully, the latter echo barwill be executed.

-eThere is another way -o errexit.


set -o errexit

Six, set -o pipefail

set -eThere is one exception, that is not suitable for pipeline command.

The so-called Pipe command is a plurality of sub-commands pipeline operator ( |) combined into one big order. Bash will return a value of the last sub-command, the entire command as the return value. In other words, as long as the last sub-command does not fail, the pipeline will always command is successful, it will still be behind the command execution, set -eit becomes ineffective.

Consider the following example.


#!/usr/bin/env bash
set -e

foo | echo a echo bar 

Execution results are as follows.


$ bash script.sh
a
script.sh:行4: foo: 未找到命令 bar 

The above code, foois a non-existent command, but foo | echo athis command is executed successfully pipeline, causing the latter echo barwill continue.

set -o pipefailTo resolve this situation, as long as a sub-command fails, the entire pipeline command fails, the script will be terminated.


#!/usr/bin/env bash
set -eo pipefail

foo | echo a echo bar 

After running the following results.


$ bash script.sh
a
script.sh:行4: foo: 未找到命令 

We can see, echo barthere is no execution.

Seven summary

setThese four parameters above command, are generally used together.


# 写法一
set -euxo pipefail

# 写法二
set -eux set -o pipefail 

Both written recommendations on the head all Bash scripts.

Another option would be in the implementation Bash script, passing the command line parameters.


$ bash -euxo pipefail script.sh

 

Guess you like

Origin www.cnblogs.com/igoodful/p/11784900.html