【GL004】Linux
shell编程
Shell 是一个命令解释权,它为用户提供了一个向 Linux 内核发送请求以便运行程序界面系统级程序,用户可以用 Shell 来启动、挂起、停止甚至是编写一些程序。
shell 编程的基本过程分为三步:
step1. 建立 shell 文件
包含任意多行操作系统命令或shell命令的文本文件;
step2. 赋予shell文件执行权限
用chmod命令修改权限;
step3. 执行shell文件
直接在命令行上调用shell程序.
示例:
step1: 建立shell文件 (可用任何建立文本文件的方法)
$ cat prog1.sh
date
Step2: 赋予执行权限: (初始文本文件无执行权限)
$ chmod 740 prog1.sh
Step3: 执行该shell程序
$ prog1.sh
prog1.sh: not found
(shell在标准搜索路径中找不到prog1.sh)
Step4: 指定路径或修改环境变量PATH后执行shell程序
$ ./prog1.sh
2024年 11月 18日 星期一 14:52:57 CST
3.shell 程序和语句
shell 程序由零或多条shell语句构成。 shell语句包括三类:说明性语句、功能性语句和结构性语句。
(1)说明性语句:
以#号开始到该行结束,不被解释执行(注释行).
(2)功能性语句:
任意的shell命令、用户程序或其它shell程序。
案例一:
read从标准输入读入一行, 并赋值给后面的变量,其语法为:
read var # 把读入的数据全部赋给var
read var1 var2 var3 # 把读入行中的第一个单词(word)赋给var1, 第二个单词赋给var2, ……把其余所有的词赋给最后一个变量.
如果执行read语句时标准输入无数据, 则程序在此停留等侯, 直到数据的到来或被终止运行。
expr命令
算术运算命令expr主要用于进行简单的整数运算,包括加(+)、减(-)、乘(\*)、整除(/)和求模(%)等操作。
$ expr 12 + 5 \* 3
27
$ expr 3 - 8 / 2
-1
$ num=9
$ sum=`expr $num \* 6 `
$ echo $sum
54
结构性语句
主要根据程序的运行状态、输入数据、变量的取值、控制信号以及运行时间等因素来控制程序的运行流程。
主要包括:条件测试语句(两路分支)、多路分支语句、循环语句、循环控制语句和后台执行语句等。
1)条件语句 if…then…fi
if [ 条件判断式 ];then
程序
fi
# 或者(推荐)
if [ 条件判断式 ]
then
程序
elif [ 条件判断式 ]
then
程序
fi
1.如果表达式为真, 则执行命令表中的命令; 否则退出if语句, 即执行fi后面的语句。
2.if和fi是条件语句的语句括号, 必须成对使用;
3.命令表中的命令可以是一条, 也可以是若干条。
案例:
#!/bin/bash
if [ $1 -ge 60 ]
then
echo 及格
elif [ $1 -lt 60 ]
then
echo "不及格"
fi
$1
是一个特殊的变量,它代表传递给脚本的第一个命令行参数。当你在命令行中运行一个脚本,并在脚本名后面添加了一些参数时,这些参数会被存储在 $1
、$2
、$3
等变量中,其中 $1
是第一个参数,$2
是第二个参数,以此类推。
test案例
例子: shell程序prog3.sh, 用法为:
./prog3.sh file
内容如下:
#The statement of if…then…else…fi
if [ -d $1 ]
then
echo "$1 is a directory"
exit (退出当前的shell程序)
else
if [ -f $1 ]
then
echo "$1 is a common file"
else
echo "unknown"
fi
fi
运行prog3.sh程序:
$ ./prog3.sh backup
backup is a directory
$ ./prog3.sh prog1
prog1 is a common file
$ ./prog3.sh abc
unknown
prog3.sh是对prog2.sh的优化, 逻辑结构更加清晰合理!
多路分支语句
【2】多路分支语句
(1)多路分支语句
case…esac
多路分支语句case用于多重条件测试, 语法结构清晰自然. 其语法为:
case 字符串变量 in
模式1)
命令表1
;;
模式2 | 模式3)
命令表2
;;
……
模式n)
命令表n
;;
esac
注:
1)case语句只能检测字符串变量
2)各模式中可用文件名元字符,以右括号结束
3)一次可以匹配多个模式用“|”分开
4)命令表以单独的双分号行结束,退出case语句
5)模式 n常写为字符* 表示所有其它模式
6)最后一个双分号行可以省略
(2)实例
实例. 程序prog4.sh检查用户输入的文件名, 用法为:
./prog4.sh string_name
# The statement of case…esac
if [ $# -eq 0 ]
then
echo "No argument is declared"
exit
fi
case $1 in
file1)
echo "User selects file1"
;;
file2)
echo "User selects file2"
;;
*)
echo "You must select either file1 or file2!"
;;
esac
循环语句
1.循环语句for
当循环次数已知或确定时,使用for循环语句来多次执行一条或一组命令。循环体由语句括号do和done来限定。格式为:
for 变量名 in 单词表
do
命令表
done
变量依次取单词表中的各个单词, 每取一次单词, 就执行一次循环体中的命令. 循环次数由单词表中的单词数确定. 命令表中的命令可以是一条, 也可以是由分号或换行符分开的多条。
如果单词表是命令行上的所有位置参数时, 可以在for语句中省略 “in 单词表” 部分。
实例:
实例:程序prog5.sh拷贝当前目录下的所有文件到backup子目录下.
使用语法为: ./prog5.sh [filename]
# The statement of for…do…done
if [ ! -d $HOME/backup ]
then
mkdir $HOME/backup
fi
flist=`ls`
for file in $flist
do
if [ $# = 1 ]
then
if [ $1 = $file ]
then
echo "$file found" ; exit
fi
else
cp $file $HOME/backup
echo "$file copied"
fi
done
echo ***Backup Completed***
2.循环语句while
语法结构为:
while 命令或表达式
do
命令表
done
while语句首先测试其后的命令或表达式的值,如果为真,就执行一次循环体中的命令,
然后再测试该命令或表达式的值,执行循环体,直到该命令或表达式为假时退出循环。
while语句的退出状态为命令表中被执行的最后一条命令的退出状态。
实例:
创建文件程序prog6, 批量生成空白文件,用法为:
prog6 file [number] ./a.sh file 6
# The statement for while
if [ $# = 2 ]
then
loop=$2 ------>根据命令行的第二个参数来确定循环的次数
else
loop=5
fi
i=1
while [ $i -lt $loop ]
do
> $1$i ------> 建立以第一个参数指定的文件名前缀,
例如以“file”开头, 变量i的值结尾的空文件名. 参见命令cmd > file
i=`expr $i + 1`
done
3.循环控制语句
break 和 continue
break n 则跳出n层;
continue语句则马上转到最近一层循环语句的下一轮循环上,
continue n则转到最近n层循环语句的下一轮循环上.
实例. 程序prog7的用法为:
prog7 整数 整数 整数 …
参数个数不确定, 范围为1~10个, 每个参数都是正整数。
(2) if [ $# = 0 ]
then
echo "Numeric arguments required"
exit
fi
if [ $# -gt 10 ]
then
echo "Only ten arguments allowed"
exit
fi
for number
do
count=`expr $number % 2`
if [ $count -eq 1 ]
then
continue
else
output="$output $number"
fi
done
echo "Even numbers: $output "
函数的调用
(7)函数
和其它编程语言一样,Shell 编程有系统函数和自定义函数。
函数调用格式:
方式1:
value_name=`function_name [arg1 arg2 … ]`
函数的所有标准输出都传递给了主程序的变量
方式2:
function_name [arg1 arg2 … ]
echo $?
获取函数的返回的状态
实例:
check_user( ) { #查找已登录的指定用户
user=`who | grep $1 | wc -l`
if [ $user –eq 0 ]
then
return 0 #未找到指定用户
else
return 1 #找到指定用户
fi
}
while true # MAIN, Main, main: program begin here
do
echo "Input username: \c"
read uname
check_user $uname # 调用函数, 并传递参数uname
if [ $? –eq 1 ] # $?为函数返回值
then echo "user $uname online"
else echo "user $uname offline"
fi
done