基本概念
shell脚本(shell script)
:为shell编写的脚本程序, 与Windows/Dos下的批处理相似,也就是用各类命令预先放入到一个文件中,方便一次性执行的一个程序文件.
Shell既是一种命令语言,又是一种程序设计语言(也就是shell脚本)。作为命令语言,它互动式地解释和执行用户输入的命令;作为程序设计语言,它定义了各种变量和参数,并提供了许多在高阶语言中才具有的控制结构,包括循环和分支。
shell 脚本范例
创建一个hello_world.sh的范例,内容如下:
#!/bin/bash -v
echo "Hello World !"
#!
是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种Shell。
执行过程如下:
方式一,作为解释器参数:
$ bash ./helloworld.sh
Hello World !
$ source ./helloworld.sh
Hello World !
$ . helloworld.sh
Hello World !
方式二,作为可执行程序:
$ ./helloworld.sh
-bash: ./helloworld.sh: 权限不够
$ chmod +x helloworld.sh
$ ./helloworld.sh
module () { eval `/usr/bin/modulecmd bash $*`
}
#!/bin/bash -v
echo "Hello World !"
Hello World !
Q:为什么上面的示例中,方式二的输出中多打印了脚本文件本身的内容?
A:答案在脚本文件的第一行,直接运行脚本文件时,第一行会告诉操作系统使用用#! 符号后面的解释器以及相应的参数来解释执行脚本文件,该文件中对应的解释器和参数是 /bin/bash -v( -v 刚好就是要打印程序的源代码);但用第一种方式时没有给 Bash 传递任何额外的参数,因此,它仅仅解释了脚本文件本身。
变量
定义变量
str="helloworld"
- 定义变量时,变量名不加$
- 注意,变量名和等号之间不能有空格
除了显式地直接赋值,还可以用语句给变量赋值,如:
for file in `ls /etc`
使用变量
使用一个定义过的变量,只要在变量名前面加美元符号,如:
str="helloworld"
echo $str
echo ${str}
变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界,比如下面这种情况:
for skill in Ada Coffe Action Java; do
echo "I am good at ${skill}Script"
done
如果不给skill变量加花括号,写成echo “I am good at s k i l l S c r i p t ” , 解 释 器 就 会 把 skillScript”,解释器就会把 skillScript”,解释器就会把skillScript当成一个变量(其值为空),代码执行结果就不是我们期望的样子了。
推荐给所有变量加上花括号,这是个好的编程习惯。
重新定义变量
已定义的变量,可以被重新定义,如:
str="helloworld"
echo $str
str="hiworld"
echo $str
- 这样写是合法的,但注意,第二次赋值的时候不能写
$str="hiworld"
,使用变量的时候才加美元符。
流程控制
if语句
if [ command ]; then
符合该条件执行的语句
fi
- 这个if后的方括号跟Java,C等语言的if后面的圆括号大不相同,它是一个可执行程序。正因为方括号在这里是一个可执行程序,方括号后面必须加空格。
多重if语句
if [ command ];then
符合该条件执行的语句
elif [ command ];then
符合该条件执行的语句
else
符合该条件执行的语句
fi
说明:
- bash shell会按顺序执行if语句,如果command执行后且它的返回状态是0,则会执行符合该条件执行的语句,否则后面的命令不执行,跳到下一条命令。
注意:
- shell中流程控制语句的结尾都是与开头相反的单词,应该是一种约定。
- shell的流程控制不可为空。如果if-else分支没有语句执行,就不要写这个else。
- shell中,then和fi是分开的语句。如果要在同一行里面输入,则需要用分号将他们隔开。
- 判断不支持浮点值。
- if判断中对于变量的处理,需要加引号,以免一些不必要的错误。没有加双引号会在一些含空格等的字符串变量判断的时候产生错误。
for语句
for var in item1 item2 ... itemN
do
command1
command2
...
commandN
done
C风格的for
for (( EXP1; EXP2; EXP3 ))
do
command1
command2
command3
done
shell脚本常用命令
字符处理领域:grep、awk、sed三剑客
grep
负责找出特定的行awk
能将行拆分成多个字段sed
实现更新替换插入删除等写操作。
xargs
:将标准输入转为命令行参数。
curl
:用来请求 Web 服务器。它的名字就是客户端(client)的 URL 工具的意思。
注释
单行注释使用#
即可。shell里没有多行注释。
注意事项
正确使用 source
和 .
(在bash里,source和.是等效的,他们都是读入shell脚本的内容并执行其内容)
- 仅使用
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脚本编程30分钟入门
xargs 命令教程
curl 的用法指南
awk 入门教程
Shell 编程范例