shell程序设计入门(二)

shell程序设计入门(二)

导语

shell语法

变量

shell变量和C语言的标识符命名的要求类似,在shell中,可以在变量名前加$访问其内容,然后可以用echo输出它

与echo对应的是read,它用来把用户的输入赋给变量,需要注意的事,脚本文件中参数以空白字符分割,如果一个参数包括多个空白符,就需要用引号引起来,并且单引号和双引号的操作方式是不一样的

引号

如果把$变量表达式放在双引号里,程序执行到该行会把变量替换成应有的值,如果放在单引号里就不会发生替换现象,下面是一个简单的示例程序

#!/bin/sh

string="This is a test"

echo $string
echo "$string"
echo '$string'
echo \$string

echo Please input
read string

echo '$string' now is $string
exit 0

通过这个程序可以看到单双引号以及echo还有read的使用和区别

环境变量

Linux系统的环境变量和Window其实类似,都是设定好的变量,将它们和用户在脚本中定义的区分开,它们一般是大写,书上给出的常用环境变量如下

参数变量

脚本在调用的时候是可以提供参数的,即使没有传递参数,环境变量依然存在,只不过它们的值为0,书上给出的参数变量如下

下面是一个简单的展示脚本相关变量的程序

var="Test"
echo $var
echo "程序$0正在运行$"
echo "第二个参数是$2"
echo "第一个参数是$1"
echo "参数列表是$*"
echo "用户的主目录是$HOME"

echo "请输入变量的新值"
read var

echo $var
echo "程序允许完成"
exit 0

运行的结果如下

条件

shell里的test/[ 更像是为了完善if判断而衍生的结构,并且由于test这个单词十分常用,甚至很多程序的名字就有,因此用[来搭配if更为常见,具体的字符串比较、算术比较和文件条件测试在使用的时候查阅即可,这里不多赘述

test和[的用法如下

test -f <filename>
[-f <filename>]

与if 搭配的示例如下

if test -f show_var
then
...
fi
#等价于
if [ -f show_var ]
then
...
fi
#等价于
if [ -f show_var ]; then
...
fi

书上给出了一个能够展现对应功能的脚本

if [ -f /bin/bash ]; then
    echo "文件/bin/bash存在"
fi

if [ -d /bin/bash ]; then
    echo "/bin/bash是一个目录"
else
    echo "/bin/bash不是一个目录"
fi

该脚本的目的是检测/bin/bash是否是文件,以及是否是脚本,执行的结果如下

控制结构

if else

与C语言类似,shell也是用if else语句来实现逻辑上的判断和控制的,不同的是shell的if else更复杂一些,具体用法如下

if condition
then
	statements
elif condition
then
	statements
else
	statemens
fi

这里直接给出书上的参考脚本并解释

c#!/bin/sh
echo "Is it moring? Please answer yes or no"
read timeofday

if [ $timeofday = "yes" ]#探讨这里加不加""
then
	echo "Good morning"
elif [ $timeofday = "no" ]#同上
then
	echo "Good afternoon"
else
	echo "Can't recognized"
	exit 1
fi

exit 0

结果如下

当然,这里的程序采用的是书上的第二个版本,它的问题是如果在输入的时候直接打回车,会导致timeofday变量没有接受到任何值变为空,于是判断语句的左边便缺失,判断语句无法执行

在shell当中,空和空句并不是一个东西,为了改善这个情况,需要吧$timeofday加上双引号,这样在判断的时候判断语句左边就是空句,就可以进行判断了

循环

for

shell中for的用法很简单,和python或者C++11有点像

for var in values
do
	statements
done

与其他高级程序设计语言不同的是,这里的values是一个列表,里面通常是一些字符串(文件名或参数名

以下是一个使用通配符匹配的简单脚本,它负责找到当前目录下所有f开头的文件并打印它们的名字

for file in $(ls f*); do
    echo $file
done
exit 0

执行的结果如下

while

while的用法也很简单,它一般用于不知道循环的次数或者持续寻找的情况

while condition; do
	statements
done

以下是书上给出的一个判断密码的简单例子

echo "请输入密码"
read password

while [ "$password" != "password" ]; do
    echo "请重试"
    read password
done
echo "密码正确"
exit 0

运行结果如下

until

until是C语言没有的关键字,在shell中它与while条件反过来了,也就是循环执行到条件为真,while是循环执行到条件为假,一般来说,如果循环至少执行一次就用while,否则就用until

until condition
do
	statements
done

这里给出上一节while程序的until版本

echo "Enter password"
read input

until [ "$input" = "password" ];do
    echo "wrong password"
    read input
done
exit 0

运行的结果如下

case

shell中case的用法比较复杂,和C语言的完全不一样,并且花样繁多,例如允许合并匹配、执行多条语句等

这里直接给出书上的最优程序及其运行结果

echo "Is it morning? Please answer yes or no"
read timeofday

case "$timeofday" in
    yes | y | Yes |YES )
        echo "Good Morning"
        echo "Up bright and early this morning"
        ;;
    [nN]*)
        echo "Good Afternoon"
        ;;
    *)
        echo "Sorry, answer not recognized"
        echo "Please answer yes or no"
        exit 1
        ;;
esac
exit 0

AND和OR

AND

shell里的and(即&&)和C语言中的&&意思并不一样,它的作用是检查前一条命令的返回值,具体来说

order1 && order2 && order3......

这样的一条shell命令,会从左到右依次执行,如果当前执行的命令返回为true,下一条命令才能执行,否则就停止,可以理解为串联,中间一旦断了,后面都接不上

OR

shell的or(||)和C语言中的||意思也是不一样的,它和&&相反

order1 || order2 || order3......

该shell指令从左到右依次执行,直到执行到第一个返回true的命令或执行完所有命令为止,换句话说,当一条命令的返回值为false,它的下一条命令才能执行,正好和&&相反

函数

作为编程语言,shell同样可以构造函数并提供调用,调用的格式如下,和C语言很像

funciton_name()
{
	statements
}

和C语言一样,shell编程中也会遇到局部变量和全局变量的问题,书上给出了一个相关的脚本如下

#!/bin/sh
sample_text="全局变量"
foo()
{
	local sample_text="局部变量"
	echo "函数foo正在运行"
	echo $sample_text
}

echo "以下为sample_text在函数执行前的值"
echo $sample_text

foo

echo "以下为sample_txt在函数执行后的值"
echo $sample_text

exit 0

下面是运行结果,可以看到,在函数体内是以局部变量优先的

在此基础上,shell脚本中的函数可以调用脚本的参数作为函数的参数来使用,书上的例子如下

#!/bin/sh

yes_or_no(){
	echo "Is your name $* ?"
	while true
	do
		echo -n "Enter yes or no: "
		read x
		case "$x" in
			y | yes ) return 0;;
			n | no ) return 1;;
			* )		 echo "Answer yes or no"
		esac
	done
}

echo "Original parameters are $*"

if yes_or_no "$1"
then
	echo "Hi $1, nice name"
else
	echo "Never mind"
fi
exit 0

执行的结果如下,可以看到输入的xxx从脚本的参数变成了函数的参数并进入了函数

总结

由于该章篇幅过多,因此本篇只选择了语法中的变量到函数的部分,需要注意的是shell和C语言有很多相似之处,使用的时候注意理解和区分

参考文献

  1. 《Linux程序设计(第4版)》
相关推荐
Mr_Xuhhh2 分钟前
重生之我在学环境变量
linux·运维·服务器·前端·chrome·算法
Ajiang28247353041 小时前
对于C++中stack和queue的认识以及priority_queue的模拟实现
开发语言·c++
幽兰的天空1 小时前
Python 中的模式匹配:深入了解 match 语句
开发语言·python
内核程序员kevin3 小时前
TCP Listen 队列详解与优化指南
linux·网络·tcp/ip
Theodore_10224 小时前
4 设计模式原则之接口隔离原则
java·开发语言·设计模式·java-ee·接口隔离原则·javaee
----云烟----6 小时前
QT中QString类的各种使用
开发语言·qt
lsx2024066 小时前
SQL SELECT 语句:基础与进阶应用
开发语言
开心工作室_kaic6 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端
向宇it7 小时前
【unity小技巧】unity 什么是反射?反射的作用?反射的使用场景?反射的缺点?常用的反射操作?反射常见示例
开发语言·游戏·unity·c#·游戏引擎
武子康7 小时前
Java-06 深入浅出 MyBatis - 一对一模型 SqlMapConfig 与 Mapper 详细讲解测试
java·开发语言·数据仓库·sql·mybatis·springboot·springcloud