跳至主要內容

Linux Shell 极速教程

西风逍遥游大约 3 分钟

Linux Shell 极速教程

Linux 作为一款超流行的操作系统,Shell的易用性和组合型功不可没。Linux的哲学就是每一个工具只做一件事,把这件事做好,然后通过shell把功能组合起来。这样脚本就能够将大量的工作自动化。

Linux下的shell主要有sh, csh, bash, zsh, fish等几种。由于fish有着特殊的文法,我这里就主要接受bash/zsh系列的经典shell用法以及技巧。

了解的你的Shell

shell是一种解释型语言,你可以调用其解释器来解析某个shell脚本。一般在Linux下,正在使用的shell会导出变量名$SHELL,你可以打开默认命令行,通过打印这个变量来查看系统默认的shell解释器:

> echo $SHELL
/bin/zsh

当然,如果在脚本中,那当前运行着的也许是非默认shell,比如某个程序调用你的脚本,但其配置使用的是自己的bash,这也是可能的,所以如果想检测当前命令是什么,打印$0是一个不错的选择:

> echo $0
bash

这里$0表示的是命令行参数中的0号元素,其实就是调用的命令,在Linux中,命令行参数一般由一个数组构成,就是一般你写C语言时,main函数的参数:

int main(int argc, char** argv) 

命令行参数在shell中也一样,你可以用$0~$N来获取这些参数,全部是字符串:

/usr/bin/echo hello world 123

你会得到如下的一个列表:

$0$1$2$3
/usr/bin/echohelloworld123

但如果你要用bash运行一个脚本时则不一样了,比如你运行如下指令,这时被执行的代码./script.sh就成为了$0

/usr/bin/bash ./script.sh hello world 123
$0$1$2$3
./script.shhelloworld123

获取脚本的当前存放位置

我们写脚本一般是为了将某些工作自动化,比如我们想给我们的开源软件写一个发布脚本,功能是编译并创建编译后的软件包。我们可以先检测一下系统有没有构建工具和依赖的软件,如果没有,则提示错误,接下来编译,运行测试,最后打包。

这样的脚本显然应该放到代码仓库里,然而我们运行脚本的当前目录往往是不确定的,但脚本却要去找到代码仓库的目录,或者说想知道脚本自己放到了哪。这时我们就可以用$0进行一个相对跳转来获取目录:

SCRIPTPATH="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"

这个获取思路是,由于一个脚本是由类似/usr/bin/bash ./path/script.sh这样的命令调用的,那么$0里就包含了脚本的相对位置信息,那么我们先用cd跳转到脚本所在目录,再运行pwd获取目录的路径就可以了。

启动异常时中断

在一个bash脚本中,当你在运行一系列指令时,默认是会依次运行所有指令的。 但有时你希望出错时能立即停下来,比如如果测试失败,则不继续执行下面指令去打包编译好的代码。这时,你可以通过如下设置来让出错后立即中断脚本:

set -e

command1
command2

设置-e后,如果command1返回非0值,则command2不会执行。

输出流重定向

重定向类型命令格式
标准输出流run command > output.log
标准异常流run command > error.log
重定向两者到同一个文件run command > out_and_err.log 2>&1