1. shell脚本编程
2. 运行 Shell 脚本有两种方法
3. 变量
4. 本地变量
5. 环境变量
6. 参数变量
7. 多行注释
8. if条件判断
9. test
命令
10. 循环
11. 算数运算
12. 测试实例
在正式开始介绍shell编程之前,我们先来简单的了解一下什么是解释型语言和编译型语言。
Shell 脚本(shell script),是一种为 shell 编写的脚本程序。业界所说的 shell 通常都是指 shell 脚本。shell编程作为解释型语言,shell程序在运行时需要shell提供解释,比如bash解释器。
第一种:
chmod u+x my.sh
./my.sh
第二种:
bash my.sh
#!
是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell。
#
用于注释
实例:编写如下内容文件,命名为my.sh
#!/bin/bash #指定用/bin/bash作为解释器
echo "Hello World !" #echo 命用于向窗口输出文本
说明:Linux平台不以后缀名区分文件类型,一般shell脚本文件通常取名为 *.sh
此外,作为一个解释型语言shell脚本也只能在Linux等平台运行,就通用而言没有另一款解释型语言Python强。但shell脚本也具有自身的优点,比如在Linux平台上进行批量操作时,或是其他一些对文件的操作时,虽然前者可以手动输入命令执行,后者可以用c语言等的高级编程语言实现,但对于shell脚本或者说shell命令来说也许只要一个命令就可以搞定。
定义变量无需指示变量的类型,可以这么说,你想让它是什么类型,它就是什么类型。
注意,变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样。同时,变量名的命名须遵循如下规则:
如name
abc
str
等都是正确的变量名。
变量的赋值
以下三种赋值方式没有区别
str=hello
str1=“hello”
str2='hello'
$
这个符号为取值符号,要使用变量中储存的内容时,变量名前加上$
符号。同时如果要输出类似字符串 str=$str
需要在字符串两边加上' '
单引号,加" "
双引号没有作用,在shell脚本中双引号相对于单引号是一个弱引用,这与我们平时学的编程语言有些不一样。
echo str=$str
echo "str=$str"
echo 'str=$str'
保存上述代码,执行
这次我们使用了对文件增加执行权限的方法运行shell脚本程序,可以看到运行结果和我们预期的一致。
如下程序,用read
命令读取一行输入,存入变量line
中,然后输出
echo "input:"
read line
echo "line=$line"
当一个shell脚本程序开始执行时,一些变量会根据环境设置中的值进行初始化。这些变量通常用 ,大写字母做名字,以便把它们和用户在脚本程序里定义的变量区分开来,后者按惯例都用小写字母做名字。具体创建的变量取决于你的个人配置。在系统的使用手册中列出了许多这样的环境变量
$HOME | 当前用户的家目录 |
---|---|
$PATH | 以冒号分隔的用来搜索命令的目录列表 |
$PS1 | 命令提示符,通常是$字符 |
$PS2 | 二级提示符,用来提示后续的输入,通常是 > 字符 |
IFS | 输入域分隔符。当shell读取输入时,它给出用来分隔单词的一组字符,通常是空格、制表符和换行符 |
$0 | shell脚本的名字 |
$# | 传递给脚本的参数的个数 |
$$ | shell脚本的进程号 |
在要执行脚本程序后跟上相应的参数,在执行脚本时会把相应的参数保存在这些变量中。
参数变量 | 说明 |
---|---|
$1,$2,$3, ··· | 脚本程序的参数 |
$* | 在一个变量中列出所有参数,各个参数之间使用环境变量IFS中的第一个字符分隔开 |
$@ | 是$*的一种精巧的变体,不使用IFS环境变量 |
测试:
# 环境变量
echo "PATH=$PATH" #目录列表
echo "HOME=$HOME" #家目录
#
echo "\$0=$0" #shell脚本名字
echo "\$#=$#" #传递给脚本名字
echo "\$$=$$" #脚本进程号
# 参数,最多9个
echo "\$1=$1"
echo "\$2=$2"
echo "\$3=$3"
echo "\$9=$9"
这里$1
~$9
都没有输出是因为,在执行的时候没有传入参数,重新再执行一次
可以看到我们传入了两个参数,分别是$1=hello
$2=world
,它们分别被保存在$1
$2
中。需要注意的是,参数变量中不能直接使用数字10
,如果要使用10
及以上的参数变量请使用{10}
这种语法。
接下来,我们来玩一个有意思的
PS1
是一级提示符环境变量,里面保存的是命令解释器的提示行的输出格式。我们通过命令解释器输入以下信息:
PS1='System error: '
此命令是修改一级提示符PS1
的值,改变命令解释器中的提示信息。
记得提前把原来PS1
中的信息保存,然后通过相同的方法恢复。或者可以根据个人喜好自行配置命令提示符样式。
通过<<
输入重定向命令实现,详情请点我
<
<<EOF
echo hello world!
EOF
基本语法:
if [ 条件 ] #以 if 开头,注意用的是 [ ] 而不是我们熟悉的()
then #如果if成立,then
语句:
elif [ 条件 ] #else if 的缩写,这是语法规定,不可以写成else if
then
语句:
else #else
语句:
fi #以 if 开始 以 fi 结束
test
命令可以使用test
命令,执行一些操作
test命令可以使用的条件类型可以归为3类:字符串比较、算术比较和与文件有关的条件测试,表2-4、表2-5和表2-6描述了这3种条件类型。
if
测试实例:1.屏幕上输入数字,判断是否等于123
#!/bin/bash
echo "input:"
read line #读取键盘输入的一行
if [ "$line" = "123" ] #字符串与等号之间留空格,比较字符串相等
then
echo "input==123"
else
echo "input!=123"
fi
exit 0
2.输入数字,比较算数相等
#!/bin/bash
echo "input:"
read line #读取键盘输入的一行
if [ "$line" -eq 10 ] #用 -eq 比较算数相等
then
echo "相等"
else
echo "不相等"
fi
exit 0
1.for
循环
for 条件 #条件满足就执行
do
语句:
done
2.while
循环
while 条件 #条件满足就执行
do
语句:
done
3.until
循环
until 条件 #直到条件满足,否则一直执行
do
语句:
done
1.循环三次打印i
的值,每次睡眠一秒
#!/bin/bash
for i in 1 2 3
do
echo "i=$i"
sleep 1
done
# 写成下面这样也可以
#for((i=1;i<=10;i++))
#{
# echo $i
# sleep 1
#}
exit 0
2.利用循环打印ls
命令输出目录
注: 要使用对应命令而不是字符,有两种方式,可以用$(ls)
或\`ls\
,
#!/bin/bash
# 命令 $(ls) `ls`
#for i in $(ls)
for i in `ls`
do
echo "i=$i"
done
exit 0
3.while
死循环。只要条件为真就会一直执行下去,那么可以依据这一特点设计死循环。例如 判断1 = 1
相等的操作,或是 :
操作符,或是 echo hello world
打印输出语句。
while [ 1 = 1 ] # while [ : ] 或 while [ echo "死循环" ]
do
done
4.在当前目录下寻找a.c文件,如果没找到,一直循环,直到找到为止
#!/bin/bash
until [ -f a.c ]
do
echo "not find a.c"
sleep 1
done
echo "find a.c"
exit 0
在执行次脚本后,该程序会一直再当前目录寻找a.c
文件,如果在当前目录创建a.c
文件,该程序就会停止,并且输出find a.c
如果相对一个变量进行算数运算,可以通过let
或expr
如下两种方式进行
#!/bin/bash
i=1
let "$i + 1" #取 i的值加一
i=`expr $i + 1` # i赋值为 变量i的值加一
echo $i
exit 0
编写测试实例:
#!/bin/bash
i=1
while [ "$i" -lt 10 ]
do
echo "i=$i"
i=`expr $i + 1`
done
exit 0
1.编写一个程序,实现输入成绩(0~100)转换成对应等级(A~E)
#!/bin/bash
# 输入成绩显示等级 A~E
echo "请输入成绩(0~100)"
read line
if [ $line -ge 0 ] && [ $line -lt 60 ]
then
echo "E 不及格"
elif [ $line -ge 60 ] && [ $line -lt 70 ]
then
echo "D 及格"
elif [ $line -ge 70 ] && [ $line -lt 80 ]
then
echo "C 良好"
elif [ $line -ge 80 ] && [ $line -lt 90 ]
then
echo "B 优秀"
elif [ $line -ge 90 ] && [ $line -le 100]
then
echo "A 非常优秀"
else
echo "输入成绩错误"
fi
exit 0
2.实现简单的密码验证检测机制,即,连续输入三次错误,视为登录失败。
#!/bin/bash
# 密码检测,三次输入检测机制
echo "input passwd:"
i=0
while [ $i -lt 3 ]
do
read passwd
if [ $passwd = "wq" ] #默认密码 wq
then
echo "密码正确"
break
else
echo "密码错误,请重新输入"
fi
let "i+=1"
continue
done
if [ $i -eq 3 ]
then
echo "错误次数过多,登录失败"
fi
exit 0