To my CSDN

shell脚本编程(一) 变量、条件判断、循环

目录

  1. shell脚本编程
  2. 运行 Shell 脚本有两种方法
  3. 变量
  4. 本地变量
  5. 环境变量
  6. 参数变量
  7. 多行注释
  8. if条件判断
  9. test命令
  10. 循环
  11. 算数运算
  12. 测试实例





shell脚本编程

在正式开始介绍shell编程之前,我们先来简单的了解一下什么是解释型语言和编译型语言。

  • 解释型:Java、Python、Shell编程
    • 运行时,需要解释器 解释执行
    • 特点:跨平台,设计解释器(win-PE格式、Linux-ELF格式)
  • 编译型:C、C++
    • 直接编译生成二进制指令,可以直接执行
    • 特点:运行效率高

Shell 脚本(shell script),是一种为 shell 编写的脚本程序。业界所说的 shell 通常都是指 shell 脚本。shell编程作为解释型语言,shell程序在运行时需要shell提供解释,比如bash解释器。

运行 Shell 脚本有两种方法:

  1. 对写好的shell脚本增加执行权限,直接执行(实际上还是通过shell完成的)
   第一种:
   chmod u+x my.sh
   ./my.sh
  1. 指定解释器执行
	第二种:
	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等都是正确的变量名。

  • 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
  • 中间不能有空格,可以使用下划线(_)。
  • 不能使用标点符号。
  • 不能使用bash里的关键字(可用help命令查看保留关键字)。

变量的赋值
以下三种赋值方式没有区别

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中的信息保存,然后通过相同的方法恢复。或者可以根据个人喜好自行配置命令提示符样式。

多行注释:

通过<<输入重定向命令实现,详情请点我
<<tag表示将开始标记 tag 和结束标记 tag 之间的内容作为输入。

<<EOF
echo hello world!
EOF

if条件判断

基本语法:

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


算数运算

如果相对一个变量进行算数运算,可以通过letexpr如下两种方式进行

#!/bin/bash

i=1
let "$i + 1"		#取 i的值加一
i=`expr $i + 1`		# i赋值为 变量i的值加一
echo $i

exit 0

编写测试实例:

  1. 循环打印 1~9
#!/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

posted @ 2019-11-15 13:37  我叫RT  阅读(808)  评论(0编辑  收藏  举报