执行Shell脚本的方式
范例1:输入重定向到bash
bash < test.sh
可以读入test.sh
中的程序,并执行。
范例2:以脚本名作为参数
其一般形式是:
bash 脚本名 [参数]
例如:
bash test.sh /usr/bin
其执行过程与范例1一样,但这种方式的好处是能在脚本名后面带有参数,从而将参数值传递给程序中的命令,使一个Shell脚本可以处理多种情况,就如同函数调用时可以根据具体问题传递相应参数。这个例子中,参数是:/usr/bin
。
范例3:以 . 来执行
如果以当前Shell(以.
表示)执行一个Shell脚本,则可以使用如下简便形式:
. test.sh [参数]
范例4:直接执行
将Shell脚本的权限设置为可执行,然后在提示符下直接执行它:
chmod +x test.sh
./test.sh
这个要求在Shell脚本开头指明执行该脚本的具体Shell,例如/bin/bash
:
#!/bin/bash
正确使用source
和.
仅使用source
和.
来执行你的环境配置等功能,建议不要用于其他用途。在Shell中使用脚本时,使用bash your_script.sh
而不是source your_script.sh
或. your_script.sh
。
当使用bash
的时候,当前Shell会创建一个新的子进程来执行你的脚本;当使用source
和.
时,当前的Shell会直接执行your_script.sh
中的代码。如果your_script.sh
中包含了类似exit 0
这样的代码,使用source
和.
执行会导致当前Shell意外退出。
Shell的执行原理
Shell接收用户输入的命令(脚本名),并进行分析。如果文件被标记为可执行,但不是被编译过的程序,Shell就认为它是一个Shell脚本。Shell将读取其中的内容,并加以解释执行。所以从用户的角度看,执行Shell脚本的方式与执行一般可执行文件的方式一样。
因此,用户开发的Shell脚本可以驻留在命令搜索路径的目录之下(通常是/bin
、/usr/bin
),像普通命令一样使用。这样也就开发出自己的新命令。如果打算反复使用编好的Shell脚本,那么采用这种方式比较方便。
变量赋值
可以将一个命令的执行结果赋值给变量。有两种形式的命令替换:
范例:获取当前工作目录并存放到变量中
例如:将当前工作目录的全路径名存放到变量dir中,输入以下命令行:
dir=`pwd`
另一种形式是:
dir=$(pwd)
数组
Bash
只提供一维数组,并没有限定数组的大小。类似于C语言,数组元素的下标由0开始编号。获取数组中的元素要利用下标。下标可以是整数或算术表达式,其值应大于或等于0。用户可以使用赋值语句对数组变量赋值。
范例:对数组元素赋值
对数组元素赋值的一般形式是:数组名[下标值]=值
,例如:
city[0]=Beijing
city[1]=Shanghai
city[2]=Tianjin
也可以用declare
命令显示声明一个数组,一般形式是:
declare -a 数组名
范例:访问某个数组元素
读取数组元素值的一般形式是:${数组名[下标]}
,例如:
bash-3.2$ echo ${city[0]}
Beijing
范例:数组组合赋值
一个数组的各个元素可以利用上述方式一个元素一个元素地赋值,也可以组合赋值。定义一个数组并为其赋初值的一般形式是:
数组名=(值1 值2 ... 值n)
其中,各个值之间以空格分开。例如:
bash-3.2$ A=(this is an example of shell script)
bash-3.2$ echo ${A[0]} ${A[1]}
this is
bash-3.2$ echo ${A[8]}
由于表中初值共有7个,所以A
的元素个数也是7。A[8]
超出了已赋值的数组A
的范围,就认为它是一个新元素,由于预先没有赋值,所以它的值是空串。
若没有给出数组元素的下标,则数组名表示下标为0的数组元素,如city
就等价于city[0]
。
范例:列出数组中所有内容
使用*
或@
做下标,则会以数组中所有元素取代。
echo ${A[*]}
echo ${A[@]}
范例:获取数组元素个数
bash-3.2$ echo ${#A[@]}
7
参数传递
假如要编写一个Shell脚本来求解两个数的和,可以怎么实现呢?为了介绍参数传递的用法,编写这样一个脚本:
bash-3.2$ cat > add
let sum=$1+$2
echo $sum
按ctrl+d保存,执行一下:
bash-3.2$ chmod a+x add
bash-3.2$ ./add 5 10
15
可以看到5和10分别传给了$1
和$2
,这是Shell自己预设的参数顺序,其实也可以先定义好变量,然后传递进去。
例如,修改上述脚本得到:
let sum=$X+$Y
echo $sum
再次执行:
bash-3.2$ X=5 Y=10 ./add
15
参数要放在执行命令的前面。
设置环境变量
export opid=True
这样子就可以,如果要登录以后都生效,可以直接添加到/etc/profile
或者~/.bashrc
里面。
键盘读起变量值
可以通过read
来读取变量值,例如,来等待用户输入一个值并显示出来:
bash-3.2$ read -p "请输入一个值:" input
请输入一个值:21500
bash-3.2$ echo "你输入了一个值为:" $input
你输入了一个值为: 21500
设置变量的只读属性
有些重要的Shell变量,赋值后不应该修改,那么可以设置它为readonly
:
oracle_home=/usr/oracle7/bin
readonly oracle_home
条件测试命令 test
语法:test 表达式
如果表达式真,则返回真,否则,返回假。
范例:数值比较
先给出数值比较时常见的比较符:
-eq =
、-ne !=
、-gt >
、-ge >=
、-lt <
、-le <=
。其实很好记的,eq就是equal,ne就是not equal,gt就是great than,ge就是great or equal,lt就是less than,le就是less or equal。
建议学会自己查命令的说明书,两步走:1. 使用
type 命令名
来查看命令是内建(shell builtin)的还是外部的命令。 2. 如果是内建命令就使用help 命令名
,如果是外部命令就是使用man 命令名
。
test var1 -gt var2
注意上面只是test命令的一般形式,不是具体可执行的命令。比如var1,如果你要写一个具体的命令的时候,参数名前面则要加var1。
这个命令的返回值往往是丢给if
(if is a shell keyword)。
范例:测试文件属性
文件的可读、可写、可执行,是否为普通文件,是否为目录分别对应:
-r
、-w
、-x
、-f
、-d
。对应的单词是read、write、execute、file、directory。
test -r filename
范例:字符串属性以及比较
串长度为0:-z
;非0:-n
test -z s1
范例:串比较
相等"s1"="s2"
;不相等"s1"!="s2"
还有一种比较串的方法(可以按字典序来比较):
if [['abcde' < 'abcdf']]; then echo "yeah, 小于"; fi
控制执行流程命令
范例:条件分支命令 if
if
命令举例:如果第一个参数是一个普通文件名,那么分页打印该文件;否则,如果它为目录名,则进入该目录并打印该目录下的所有文件,如果也不是目录,那么提示相关信息。
#!/bin/bash
if test -f $1
then
pr $1>&1
elif
test -d $1
then
(cd $1;pr *>&1)
else
echo $1 is neither a file nor a directory
fi