Shell脚本基础知识
#!/bin/bash #表示该脚本使用后面指定的解释器/bin/bash解释执行
echo "Hello World" #脚本功能
1.概念
Shell脚本与Windows/Dos下的批处理相似,也就是用各类命令预先放入到一个文件中,方便一次性执行的一个程序文件,主要是方便管理员进行设置或者管理用的。但是它比Windows下的批处理更强大,比用其他编程程序编辑的程序效率更高,它使用了Linux/Unix下的命令。 Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。
Shell 主要用来开发一些实用的、自动化的小工具,而不是用来开发具有复杂业务逻辑的中大型软件,例如检测计算机的硬件参数、一键搭建Web开发环境、日志分析等,Shell 都非常合适。
#! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell。
在进行shell编程时,以#开头的句子表示注释,直到这一行的结束。
2.变量
在shell编程中,所有的变量都由字符串组成,并且不需要对变量进行声明。Shell中无数据类型 。
#!/bin/sh #表示该脚本使用后面指定的解释器/bin/bash解释执行
a="hello world" #对变量赋值
echo "A is:"
echo $a #打印变量内容
echo "${a}word" #变量与其他字符在一起时用{}括起变量或者用空格隔开
2.1 环境变量
由export关键字处理过的变量叫做环境变量。通常情况下仅仅在登录脚本中使用环境变量。环境变量可以从父进程传给子进程,被子进程继承。用printenv命令可以显示当前Shell进程的环境变量。
2.2本地变量
只存在于当前Shell进程,用set命令可以显示当前Shell进程中定义的所有变量(包括本地变量和环境变量)和函数。是Shell特有的概念。
注:等号两边都不能有空格,否则被Shell解释成命令和命令行参数 。
3.Shell命令和流程控制
Shell 本身支持的命令并不多,但是它可以调用其他的程序,每个程序就是一个命令,这使得 Shell 命令的数量可以无限扩展,其结果就是 Shell 的功能非常强大,完全能够胜任 Linux 的日常管理工作,如文本或字符串检索、文件的查找或创建、大规模软件的自动部署、更改系统设置、监控服务器性能、发送报警邮件、抓取网页内容、压缩文件等。
3.1 Unix命令
在shell脚本中可以使用任意的unix命令,但是还是由一些相对更常用的命令。这些命令通常是用来进行文件和文字操作的。
echo “some text”: 将文字内容打印在屏幕上
ls: 文件列表(当前目录下)
wc –l file wc -w file wc -c file: 计算文件行数、单词数、字符数(必须指定文件)
cp sourcefile destfile: 文件拷贝
mv oldname newname : 重命名文件或移动文件
rm file: 删除文件
grep ‘pattern’ file: 在文件内搜索字符串比如:grep ‘searchstring’ file.txt
cut -b colnum file: 指定欲显示的文件内容范围
cat file: 输出文件内容到标准输出设备(屏幕)上
file somefile: 得到文件类型
read var: 提示用户输入,并将输入赋值给变量
sort file.txt: 对file.txt文件中的行进行排序
uniq: 删除文本文件中出现的行列比如: sort file.txt | uniq
expr: 进行数学运算Example: add 2 and 3expr 2 “+” 3
find: 搜索文件比如:根据文件名搜索find . -name filename -print
tee: 将数据输出到标准输出设备(屏幕) 和文件比如:somecommand | tee outfile
basename file: 返回不包含路径的文件名比如: basename /bin/tux将返回 tux
dirname file: 返回文件所在路径比如:dirname /bin/tux将返回 /bin
head file: 打印文本文件开头几行
tail file : 打印文本文件末尾几行
sed: 是一个基本的查找替换程序。可以从标准输入(比如命令管道)读入文本,并将结果输出到标准输出(屏幕)。该命
令采用正则表达式进行搜索。
3.2 管道, 重定向和 backtick
管道 (|) 将一个命令的输出作为另外一个命令的输入。 例如:grep “hello” file| wc -l 在file中搜索hello字符串然后计算行数
重定向:将命令的结果输出到文件,而不是标准输出(屏幕)。 ①写入文件并覆盖旧文件 ②加到文件的尾部,保留旧文件内容
3.3条件判断语句
Shell中条件判断语句,一般用test命令或是[ ]命令来完成,它们是条件判断语句if~then语句的基础。
#test是关键字,表示判断;EXPRESSION是被判断的语句。
$ test EXPRESSION
#中括号的左右扩弧和EXPRESSION之间都必须有空格!
$ [ EXPRESSION ]
#判断文件/home/skywang/123.txt是否存在
$ [ -f /home/skywang/123.txt ]
#判断变量val是否等于字符串“skywang”
$ [ "$val" = "skywang" ]
#判断变量num是否等于数字100
$ [ "$num" -eq "100" ]
3.3.1 test命令实现条件测试
test命令用于检测系统中某些文件是否存在,或者相关属性。
3.4文件表达式
语句 | 作用 |
---|---|
if [ -f file ] | 如果文件存在 |
if [ -d … ] | 如果目录存在 |
if [ -s file ] | 如果文件存在且非空 |
if [ -r file ] | 如果文件存在且可读 |
if [ -w file ] | 如果文件存在且可写 |
if [ -x file ] | 如果文件存在且可执行 |
3.5整数变量表达式
if [ int1 -eq int2 ] 如果int1等于int2
if [ int1 -ne int2 ] 如果不等于
if [ int1 -ge int2 ] 如果>=
if [ int1 -gt int2 ] 如果>
if [ int1 -le int2 ] 如果<=
if [ int1 -lt int2 ] 如果<
3.6字符串变量表达式
If [ $a = $b ] 如果string1等于string2,字符串允许使用赋值号做等号
if [ $string1 != $string2 ] 如果string1不等于string2
if [ -n $string ] 如果string 非空(非0),返回0(true)
if [ -z $string ] 如果string 为空
if [ $sting ] 如果string 非空,返回0 (和-n类似)
3.7 if 条件语句
单分支语句结构(第一种常用)
if [条件表达式]
then #注意:每个if语句都是以if开头 fi结束,中间并带有then
指令
fi #结束if语句,相当于end if
4.例程
#!/bin/sh
##判断变量,是否为空(如果没有或只有一个,进行默认赋值)
if [ "$1" == "" ]
then
start_date=`date -d "today last month" "+%Y%m01"`
end_date=`date -d "today" "+%Y%m%d"`
else
if [ "$2" == "" ]
then
start_date=`date -d "$1" "+%Y%m%d"`
end_date=`date -d "today" "+%Y%m%d"`
fi
fi
##判断两个变量是否有问题(可扩展,进行可用性识别)
if [ "$start_date" -gt "$end_date" ]
then
echo "ERROR! \nplease input a right date"
exit
fi
##通过循环,返回日期值(包含开始和结束日期,闭区间)
for i in `seq 0 100000`
do
t_date=`date -d "${start_date} +$(($i+1)) day" "+%Y%m%d"`
echo $t_date
cnt_days=$i
##如果循环到当天,就退出
if [ $t_date == $end_date ]
then
break
fi
done
echo "The days between two date is "+$cnt_days+" !"
5.实践中遇到的问题(持续更新)
bash: .test.sh:/bin/bash^M:解释器错误: 没有那个文件或目录,脚本文件在windows下编辑过。windows下,每一行的结尾是\n\r,而在linux下文件的结尾是\n 。用cat -A filename时可以看到这个\r字符被显示为^M
6.循环语句
for in do done
这样的结构就是一个简单的循环,将列表中的每一个条目都循环一次。
语法结构如下:
for var in con1 con2 con3...
do
程序段
done
就上面的语法结构来说,这个var的变数内容在循环工作的时候:
1 第一次循环时,var的内容是con1;
2 第二次循环时,var的内容是con2;
3 第三次循环时,var的内容是con3;
…