专栏名称: 马哥Linux运维
马哥linux致力于linux运维培训,连续多年排名第一,订阅者可免费获得学习机会和相关Linux独家实战资料!
目录
相关文章推荐
51好读  ›  专栏  ›  马哥Linux运维

编写快速安全Bash脚本的建议

马哥Linux运维  · 公众号  · 运维  · 2017-04-15 09:04

正文

作者:oschina

来源:https://www.oschina.net/translate/bash-scripting-quirks-safety-tips?print


昨天我和一些朋友聊起Bash,我意识到:即使我已经使用Bash十多年了,现在还有一些基础的杂项,我理解的并不是很清晰。 像往常一样,我认为我应该写一个博文。

我们会包含:

  • 一些bash基础知识(“你怎么写一个for循环”)

  • 杂项事宜(“总是引用你的bash变量”)

  • bash脚本安全提示(“总是使用set -u”)

如果你编写shell脚本,并且你没有阅读这篇文章中其他任何内容,你应该知道有一个shell脚本校验工具(linter),叫做 shellcheck 。使用它来使您的shell脚本更好!

我们会像讨论编程语言一样讨论bash,因为,怎么说呢,它就是。 这篇文章的目标不是bash编程详解。我不会在bash中做复杂的编程,也真的不计划学习如何去做。 但是,经过今天的思考之后,我认为明确整理下bash编程语言的一些基础知识是有用的。bash编程语言与我使用过的其他编程语言有着很大的不同。

我真的曾认为我已经知道这些东西了,但是通过写这篇文章我依旧学到了一些东西,也许你也会有所收获。

变量赋值

在bash中变量赋值按照下面的方式:

VARIABLE=2

并且你可以使用$VARIABLE(变量名)来引用变量。需要注意的是不要在=运算符的两边放置空格符,比如VARIABLE= 2、VARIABLE = 2、或者VARIABLE =2,这并不是语法错误,但是将会做完全不需要的事情(比如试图运行一个名字为2的程序,并将环境变量VARIABLE设置为空字符串)。

Bash变量并不要求全部大写,但是通常是大写的。

大多数你所使用的bash变量都是字符串。在bash中也有一些数组变量,但我并不是完全理解它们。

使用${}引用变量

有时某些变量,内容为file.txt,并且我想这样使用它:

mv $MYVAR $MYVAR__bak # wrong!

这段代码是无法工作的!它会去查找 MYVAR__bak变量,但这并不是一个真实存在的变量。

为了避免类似问题,你需要知道的仅仅是 ${MYVAR}和$MYVAR是一回事。所以你可以这样运行指令:

mv $MYVAR ${MYVAR}__bak # right!

全局变量,局部变量和环境变量

Bash有3种变量。我一般先想到(可能也是最常用)的是 环境变量 。

Linux上的每个进程实际上都有环境变量(您可以运行env查看当前设置的变量),但在Bash中,它们更易于访问。要查看名为MYVAR的环境变量,可以运行

echo "$MYVAR"

要设置环境变量,您需要使用export关键字:

export MYVAR=2

设置环境变量时,所有子进程将看到该环境变量。所以如果你运行export MYVAR=2; python test.py,python程序将MYVAR设置为2。

第二种变量是 全局变量 。同样像上面那样赋值。

MYVAR=2

在其他编程语言中他们表现得像全局变量。

还有 局部变量 ,它们的作用域只能存在于bash函数中。 我基本上从来没有使用过这样的函数(不像我写的其他编程语言),我从来没有使用过局部变量。

for循环

以下是我在bash中编写循环的方法。 此循环将从1打印到10。

for i in `seq 1 10` # you can use {1..10} instead of `seq 1 10` 
do     
 echo "$i"
done

如果你想用一行代码写这个循环,可以这样写:

for i in `seq 1 10`; do echo $i; done

我觉得这是不可能记住的(你要怎么记住在 seq 1 10 之后有一个分号,但是在 do 之后却没有了),所以我不会去记它。

你也可以写while循环,但我从来没有这样写过。

有个很酷的事情是你可以遍历另一个命令的输出。seq 1 10 将数字从1到10(每行一个)打印,这个for循环只是提取该输出并遍历它。我就经常用这种方法。

您也可以使用反引号或$()来插入命令的输出。

OUTPUT=`command`
# or 
OUTPUT=$(command)

if 语句

在 bash 中的 If 语句是相当让人讨厌去记它。你必须放在这些方括号中,而在方括号之间必须有空格,否则它不起作用。[[ 和 [ 方括号(双/单) 都工作。 这里我们真正进入 bash 的奇怪领域:[ 是一个程序(/usr/bin/[)但 [[ 是 bash 语法。[[ 更好。

if [[ "vulture" = "panda" ]]; then
 echo expression evaluated as true
else
 echo expression evaluated as false
fi

此外,您可以检查“此文件存在”,“此目录存在”等内容。例如,您可以检查文件 /tmp/awesome.txt 是否存在,如下:

If [[ -e /tmp/awesome.txt ]]; then
  echo "awesome"
fi

这通常是有用的,但我必须每次查找语法。

如果您想尝试用命令行,可以使用 test 命令,例如 test -e /tmp/awesome.txt 。 它成功会返回0,否则返回错误。







请到「今天看啥」查看全文