Shell 脚本基础知识

Unix/Linux上常见的Shell脚本解释器有bash、sh、csh、ksh等,习惯上把它们称作为一种Shell。我们常说有多少中Shell,其实说的是Shell脚本解释器。

几种常见的Shell

**sh**
sh是由Steve Bourne 开发,是 Bourne shell 的缩写,sh是Unix标准默认的shell。
**bash**
bash是由Brian Fox 和 Chet Ramey共同完成。是Bourne Again Shell的缩写。bash是linux标准默认的shell。
**ash**
ash是由Kenneth Almquist编写,linux中占用资源最少的一个小shell,它只包含24个内部命令,因而使用起来不是很方便。
**csh**
csh是linux中比较大的内核,它由以William Joy为代表的共计47位作者编成,共有52个内部命令。该shell其实是指向/bin/tcsh这样的一个shell,就是说csh就是tcsh。
**ksh**
ksh是由Eric Gisin编写,是Korn Shell的缩写,共有42条内部命令。该shell最大的优点是几乎和商业发行版的ksh完全兼容。这样就可以在不用花钱购买商业版本的情况下尝试商业版本的性能了。

**注意:bash是linux默认的shell,它基于Bourne Shell,吸收了csh和ksh的一些特性,bash完全兼容sh,就是说,用sh写的脚本可以不加修改的在bash中执行**

第一个Shll脚本

$ vi hello.sh  #新建一个shell脚本(扩展名为sh的文件,sh代表shell,扩展名并不影响脚本的执行。也可以直接起名hello)

在脚本中输入以下代码:

#!/bin/bash    # "#!"是一个约定的标记,它告诉系统需要使用哪一种Shell。
echo "Hello World!"

运行Shell的方法:

$ chmod +x hello.sh         #给文件增加执行权限
$ ./hello.sh                #执行脚本

$ /bin/sh hello.sh        #以sh运行脚本
$ /bin/bash hello.sh      #以bash运行脚本

示例:
编写一个脚本,从标准输入(stdin)中读取名字,显示在标准输出(stdout)上。

#/bin/bash

echo "What's your name?"
read NAME
echo "Hello ${NAME}"

Shell 变量

定义变量
变量名与等号直接不能有空格。变量明的命名规则需遵循如下规则:
1、首个字符必须为字母(a-z,A-Z)
2、中间不能有空格,可以使用下划线(_)
3、不能使用标点符号
4、不能使用shell里的关键字(在命令行中使用help命令可以查看保留关键字)

变量定义示例:

variableName="value"

使用变量
使用一个定义过的变量,只要在变量名前面加 $ 符号就可以了。如:

variableName="value"
echo $variableName

有些时候需要在变量名外面加上花括号帮助解释器识别变量的边界,如下面这种情况

SKILL=Ada
echo "I'm a good at ${SKILL}Script"

重新定义变量
已经定义的变量,可以被重新定义,如:

#!/bin/bash
NAME=Dave
echo "Hello ${NAME}"

NAME=Abby
echo "Hello ${NAME}"

只读变量
使用readonly命令可以将变量定义为只读变量,只读变量的值不能改变

#!/bin/bash
NAME=Dave
readonly NAME
NAME=Abby

运行脚本会报错,结果如下

./test.sh: line 5: NAME: readonly variable

删除变量
使用unset命令删除变量,变量被删除后不能再次使用;unset命令不能删除只读变量
示例:

#!/bin/bash
NAME=Dave
unset NAME
echo $NAME

运行结果不会有任何输出。

Shell特殊变量

Shell 脚本基础知识
实例

#!/bin/bash

echo "File Name : $0"
echo "First Parameter : $1"
echo "Second Parameter : $2"
echo "All Parameter : $@"
echo "All Parameter : $*"
echo "Total Number of Parameter $#"
echo "The Shell of the process ID is : $$"

运行结果:

$ ./test.sh Dave Abby
File Name : ./test.sh
First Parameter : Dave
Second Parameter : Abby
All Parameter : Dave Abby
All Parameter : Dave Abby
Total Number of Parameter 2
The Shell of the process ID is : 2752
$ echo $?     #查看./test.sh 退出状态。一般情况下成功返回0,失败返回-1
0

* $* 和 $@的区别 *
很多关于shell的书本上写当它们被双引号包含时,$* 会将所有参数作为一个整体,而$@ 会将各个参数分开。但是,我在运行脚本的时候并没有发现这样的情况。我是在Ubuntu1204版本中测试的。代码如下

#!/bin/bash


echo '$*='"$*"
echo '$@='"$@"

Shell替换

命令替换
命令替换是指shell可以先执行命令,将输出结果暂时保存,在适当的地方输出
示例:

#!/bin/bash

DATE=`date`
echo "$DATE"

变量替换
Shell 脚本基础知识
示例:

#!/bin/bash

echo ${var:-"Hello"}
echo $var

echo ${var:="Hello"}
echo $var

echo ${var:+"World"}
echo $var

unset var
echo ${var:?"message"}
echo $var

结果如下:

$ ./test.sh 
Hello

Hello
Hello
World
Hello
./test.sh: line 13: var: message

Shell的if语句

if语句通过关系运算符判断表达式的真假来决定执行那个分支,Shell有三种if语句。

  • if … fi 语句
  • if … else … fi 语句
  • if … elif … else … fi 语句

if … fi 语句的语法

if [ expression ]
then
    Statement(s) to be executed if expression is true
fi

**注意:**expression 和方括号之间必须有空格。否则会有语法错误
示例:

#!/bin/bash

a=10
b=20

if [ $a == $b ]
then
        echo "a == b"
fi

if [ $a != $b ]
then
        echo "a! = b"
fi

if … else … fi语句语法

if [ expression ]
then
    Statement(s) to be executed if expression is true
else
    Statement(s) to be executed if expression is not true
fi

示例:

#!/bin/bash

a=10
b=20

if [ $a == $b ]
then
        echo "a == b"
else
        echo "a! = b"
fi

if … elif …fi语句语法

if [ expression 1 ]
then
    Statement(s) to be executed if expression 1 is true
elif [ expression 2 ]
then
    Statement(s) to be executed if expression 2 is true
elif [ expression 3 ]
then
    Statement(s) to be executed if expression  3 is true
else
    Statements to be executed if expression not is true
fi

示例:

#!/bin/bash

a=10
b=20

if [ $a == $b ]
then
        echo "a == b"
elif [ $a -gt $b ]
then
        echo "a > b"
elif [ $a -lt $b ]
then
        echo "a < b"
else
        echo "None of the condition met"
fi

Shell运算符

bash支持很多运算符。包括算数运算符、关系运算符、布尔运算符、字符串运算符和文件测试运算符。
算数运算符
Shell 脚本基础知识
bash中实现数学运算的语法。
- 使用expr表达式计算工具。 expr 1 + 2
- [1+2]Shell 脚本基础知识 ((1+2))
使用expr时需要注意:
- 表达式和运算符之间要有空格。
- 完整的表达式要被“包含起来。

示例:

#!/bin/bash

a=10
b=20

echo "`expr $a + $b`"
echo $[$a+$b]
echo $((a+b))
echo "`expr $a - $b`"
echo "`expr $a \* $b`"   # *号需要转义
echo $[$a*$b]
echo "`expr $a / $b`"
echo "`expr $a % $b`"

关系运算符
Shell 脚本基础知识
关系运算符只支持数字,不支持字符串。除非字符串的值是数字。
示例:

#!/bin/bash

a=10
b=20

if [ $a -eq $b ]
then
        echo "a == b"
else
        echo "a != b"
fi

if [ $a -ne $b ]
then
        echo "a != b"
else
        echo "a == b"
fi

if [ $a -gt $b ]
then
        echo "a > b"
else
        echo "a < b"
fi

if [ $a -lt $b ]
then
        echo "a < b"
else
        echo "a > b"
fi

if [ $a -ge $b ];then echo "a > b";else echo "a < b";fi
if [ $a -le $b ];then echo "a < b";else echo "a > b";fi

布尔运算符
Shell 脚本基础知识
示例:

#!/bin/bash

a=10
b=20

if [ ! $a -eq $b ]; then echo "a == b"; else echo "a != b"; fi

if [ $a -lt $b -o $b -gt $a ]; then echo "a < b"; else echo "a > b"; fi

if [ $a -le $b -a $b -ge $a ]; then echo "a < b"; else echo "a > b"; fi

字符串运算符
Shell 脚本基础知识
示例:

#!/bin/bash

a="abc"
b="edf"

if [ ! $a = $b ]; then echo "a != b"; else echo "a == b"; fi

if [ $a != $b ]; then echo "a != b"; else echo "a == b"; fi

if [ -z $a -o -z $b ]; then echo "string length isn't zero";
        else echo "string length is zero"; fi

if [ -n $a -a -n $b ]; then echo "string length is zero"
        else echo "string length isn't zero"; fi

if [ $a -a $b ];then echo "string length is zero"
        else echo "string length isn't zero"; fi

文件测试运算符
文件测试运算符用于检测文件的各种属性
示例:

#!/bin/bash



if [ -b $1 ]; then echo "$1 is block file"; else echo "$1 is not block file"; fi

if [ -c $1 ]; then echo "$1 is str file"; else echo "$1 is not str file"; fi

if [ -d $1 ]; then echo "$1 is directory file"; else echo "$1 is not directory file"; fi

if [ -f $1 ]; then echo "$1 is ordinary file"; else echo "$1 is not ordinary file"; fi

if [ -g $1 ]; then echo "$1 SGID bit"; else echo "$1 not SGID bit"; fi

if [ -k $1 ]; then echo "$1 Sticky bit"; else echo "$1 not Sticky not bit"; fi

if [ -p $1 ]; then echo "$1 is pipe file"; else echo "$1 is not pipe file"; fi

if [ -u $1 ]; then echo "$1 SUID bit"; else echo "$1 not SUID bit"; fi

if [ -r $1 ]; then echo "$1 is read file"; else echo "$1 is not read file"; fi

if [ -w $1 ]; then echo "$1 is write file"; else echo "$1 is not write file"; fi

if [ -x $1 ]; then echo "$1 is execute file"; else echo "$1 is not execute file"; fi

if [ -s $1 ]; then echo "$1 is not zero"; else echo "$1 is  zero"; fi

if [ -e $1 ]; then echo "$1 exists"; else echo "$1 not exists"; fi

运行结果:

相关推荐