shell 脚本入门笔记

基本格式

#!/bin/bash
echo 'Hello World'

#!/bin/bash:脚本的第一行声明了脚本的解释器,对于 shell 脚本解释器通常为 /bin/bash,当然如果是 python 脚本也可以写成 #!/bin/python

第一行之后的所有内容就是具体的命令,变量以及函数了。

运行方式

# 使用脚本中声明的解释器解释执行,如果未声明则使用当前 shell 解释执行。
./script.sh

# 使用指定的解释器执行
# 使用 /bin/sh 解释执行
sh script.sh
# 使用 /bin/bash 解释执行
bash script.sh

变量

永久环境变量

本质属于文件,对于所有 shell 均可访问。

临时环境变量

只允许当前 shell 以及其子 shell 访问。一般通过 export 来设置。

export VAR_NAME=alice

临时变量

仅仅允许当前 shell 访问。直接在声明即可。shell 脚本中不存在高级语言中局部变量这个概念,也就是 shell 脚本中任何位置声明的变量均为全局变量。

var1=1

特殊变量

变量含义
$0当前脚本的文件名
$n传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。
$#传递给脚本或函数的参数个数。
$*
传递给脚本或函数的所有参数。
$@传递给脚本或函数的所有参数。被双引号(” “)包含时,与 $* 稍有不同,下面将会讲到。
$?
上个命令的退出状态,或函数的返回值。
$$当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。

\$* 和 \$@

这两个变量在不使用双引号包裹的时候完全一样

#!/bin/bash
function foo()
{
    for var in $*
    do
        # -e 表示启用转义字符
        echo -e "$var\n"
    done
}

foo 1 2 3 4 5
#!/bin/bash
function foo()
{
    for var in $@
    do
        # -e 表示启用转义字符
        echo -e "$var\n"
    done
}

foo 1 2 3 4 5

上面两个脚本的执行结果一样:

1
2
3
4
5

但是一旦被双引号包裹就不一样了

#!/bin/bash
function foo()
{
    for var in "$*"
    do
        # -e 表示启用转义字符
        echo -e "$var\n"
    done
}

foo 1 2 3 4 5

输出为 1 2 3 4 5[换行]

#!/bin/bash
function foo()
{
    for var in $@
    do
        # -e 表示启用转义字符
        echo -e "$var\n"
    done
}

foo 1 2 3 4 5

输出结果依旧为

1
2
3
4
5

基础算数运算

可以进行简单的四则运算。但是 bash 不支持浮点运算,所以除法会直接截断小鼠部分。同时由于 * 在 shell 中有特殊的含义,所以必须使用 \ 进行转义才能使用乘法。

# 结果为 3
expr 1 + 2

# 结果为 -1
expr 1 - 2

# 结果为 6
expr 2 \* 3

# 结果为 2
expr 5 / 2

条件判断

Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。 test 可以用 [] 代替,如 test $var1 -eq $var2[ $var1 -eq $var2 ] 等价。但是不允许省略空格,也就是说 [$var1 -eq $var2] 是错的。

数字比较

参数作用举例
-eq相等则为真test $var1 -eq $var2
-ne不等则为假test $var1 -ne $var2
-gt大于则为真test $var1 -gt $var2
-ge大于等于则为真test $var1 -ge $var2
-lt小于则为真test $var1 -lt $var2
-le小于等于则为真test $var1 -le $var2
数字比较

字符串比较

参数作用举例
=等于则为真test $str1 = $str2
!=不等则为真test $str1 != $str2
-z字符串长度为零则为真test -z $str1
-n字符串长度不为零则为真test -n $str1
字符串比较

文件判断

参数作用举例
-e如果文件存在则为真test -e $filename
-r如果文件存在且可读则为真test -r $filename
-w如果文件存在且可写则为真test -w $filename
-x如果文件存在且可执行则为真test -x $filename
-s如果文件存在且至少有一个字符则为真test -s $filename
-d如果文件存在且为目录则为真test -d $filename
-f如果文件存在且为普通文件则为真test -f $filename
-c如果文件存在且为字符型特殊文件则为真test -c $filename
-b如果文件存在且为块特殊文件则为真test -b $filename
文件判断

流程控制

if

语法

if boolean ; then
    # TODO
fi

if boolean
then
   # TODO
fi

举例

shell 代码

#!/bin/bash
if [ 1 -eq 2 ] ; then
    echo '1 == 2'

等价 C 代码

if (1 == 2) {
    printf("1 == 2");
}

if···else

语法

if boolean ; then
    # TODO
else
    # TODO
fi

if boolean
then
    # TODO
else
    # TODO
fi

举例

shell 代码

#!/bin/bash
if [ 1 -eq 2 ] ; then
    echo '1 == 2'
else
    echo '1 != 2'
fi

等价 C 代码

if (1 == 2) {
    printf("1 == 2");
} else {
    printf("1 != 2");
}

if···elif

if boolean ; then
    # TODO
elif boolean ; then
    # TODO
fi

if boolean
then
    # TODO
elif boolean
then
    # TODO
fi

for

语法

for var in item0 item1 item2 ....
do
    # TODO
done

举例

#!/bin/bash
for num in 1 2 3 4 5
do
    # -e 代表开启字符转义
    echo -e "${num}\n"
done 

结果

1
2
3
4
5

while

语法

while boolean
do
    # TODO
done

举例

shell 代码

#!/bin/bash
max=6
num=0
while [ $num -lt $max ]
do
    echo -e "${num}\n"
    num=`expr $num + 1`
done

等价 C 代码

int max = 6, num = 0;
while (num < max) {
    printf("%d\n", num);
    num += 1;
}

函数

语法

# 声明函数(无论有无参数括号内均为空)
function name()
{
    # TODO
    return value
}

# 调用参数,后面跟上若干的参数
name 1 2 3 ...

其中 function 可以省略,return 也可以省略,返回值默认为最后一条指令的执行结果,return 只允许接数字,且范围为$[0,255]$。

举例

#!/bin/bash

function sum()
{
    ret=0
    for num in $@
    do
            ret=`expr $ret + $num`
    done
    return $ret
}

# 计算 1 + 2 + 3
sum 1 2 3
echo $?

双引号、单引号和反引号

双引号

双引号中允许使用变量。

#!/bin/bash
str=World
echo "Hello $str"

结果为 Hello World。

单引号

单引号中的内容将原文输出,但是不对转义符生效。

#!/bin/bash
str=World
echo 'Hello $str'

结果为 Hello $str。

反引号

会将反引号中的命令作为返回值

#!/bin/bash
list=`ls`
echo $list

结果是当前目录中的文件。

$()

$() 类似函数一样让我们将某个命令赋值给某个变量,当使用该变量时才会执行对应的命令并将返回值作为变量的值。

(())

扩展运算,支持了 C 语言大部分的写法。

  • 在双括号结构中,所有表达式可以像c语言一样,如:a++b-- 等。
  • 在双括号结构中,所有变量可以不加入:$ 符号前缀。
  • 双括号可以进行逻辑运算,四则运算。
  • 双括号结构 扩展了 forwhile, if 条件测试运算
  • 支持多个表达式运算,各个表达式之间用 , 分开。
#!/bin/bash
num=1
((num++))
((num=num+1+2-3*4/5))
((num+=1+2-3*4/5))

# 打印 [0...9]
for((i=0;i<10;i++))
do
    echo -e "$((i))\n"
done

# 如果 5 能被 2 整除则输出 true,反之输出 false
if ((5%2==0)) ; then
    echo 'true'
else
    echo 'false'
本文作者:ADD-SP
本文链接https://www.addesp.com/archives/927
版权声明:本博客所有文章除特别声明外,均默认采用 CC-BY-NC-SA 4.0 许可协议。
暂无评论

发送评论 编辑评论


上一篇
下一篇