理解expr命令的作用
能够使用(())进行整数的数学运算
能够使用let进行整数的数学运算
能够使用bc进行数学运算
掌握流程控制语句的使用
掌握自定义函数的使用
掌握Shell重定向输入与输出
expr (evaluate expressions 的缩写),译为“表达式求值”。Shell expr 是一个功能强大,并且比较复杂的命令,它除了可以实现整数计算,还可以结合一些选项对字符串进行处理,例如计算字符串长度、字符串比较、字符串匹配、字符串提取等.
计算语法
1expr 算术运算符表达式2# 例如: expr 1 + 1 返回: 23# 例如: expr \( 10 + 10 \) \* 2 + 100 返回:140获取计算结果赋值给新变量语法
xxxxxxxxxx21result=`expr 算术运算符表达式`2# 例如: result=`expr 1 + 1` 输出result得到结果: 2###
计算字符串的长度语法
xxxxxxxxxx21expr length 字符串2# 例如: expr length "itheima" 返回: 7截取字符串语法
xxxxxxxxxx41expr substr 字符串 start end2# start 截取字符串的起始位置, 从1开始3# end 截取字符串的结束位置, 包含这个位置截取4# 例如 expr substr "itheima" 1 2 返回: it获取第一个字符在字符串中出现的位置语法
xxxxxxxxxx21expr index 被查找字符串 需要查找的字符2# 例如 expr index "itheima" t 会返回: 2 正则表达式匹配1语法
xxxxxxxxxx71expr match 字符串 正则表达式2# 正则表达式默认带有^ , 代表以什么开头3# 返回值为符合匹配字符的长度, 否则返回为04# 例如: expr match "itheima" ".*m" 会返回: 65# 正则表达式通配符"."代表任意一个字符6# 正则表达式通配符"*"代表签名的字符可以出现0到多次7# ".*m" 含义为匹配字符串中m前面的字符串长度 正则表表达式匹配2语法, 功能与语法1一样
xxxxxxxxxx41expr 字符串 : 正则表达式2# 正则表达式默认带有^ , 代表以什么开头3# 返回值为符合匹配字符的长度, 否则返回为04# 例如: expr "itheima" : ".*m" 会返回: 6
需求
xxxxxxxxxx41# 四则运算: ( 10 + 10 ) * 2 + 1002# 计算"itheima"字符串的长度3# 获取"itheima"字符串中"t"第一个字符在字符串中出现的位置4# 正则表达式match匹配查找itheima字符串中m前面任意字符的总长度
cal1.sh脚本文件代码
x12# 四则运算3result=`expr \( 10 + 10 \) \* 2 + 100`4echo "(10+10)*2+100=${result}"56# 计算字符串的长度7echo "itheima字符串长度=`expr length "itheima"`"89# 获取第一个字符在字符串中出现的位置10echo "itheima字符串中第一个t的位置=`expr index "itheima" t`"1112# 正则表达式匹配113echo "正则表达式match匹配查找itheima字符串中m前面任意字符的总长度=`expr match "itheima" ".*m"`"1415# 正则表达式匹配216echo "正则表达式匹配查找itheima字符串中m前面任意字符的总长度=`expr "itheima" : ".*m"`"
运行效果
双小括号 (( )) , 用于进行数学运算表达式的执行 , 将数学运算表达式放在((和))之间。
可以使用$获取 (( )) 表达式命令的结果,这和使用$获得变量值是一样的。
xxxxxxxxxx11((表达式))
| 运算操作符/运算命令 | 说明 |
|---|---|
| ((a=1+6)) ((b=a-1)) ((c=a+b)) | 这种写法可以在计算完成后给变量赋值。以 ((b=a-1)) 为例, 即将 a-1 的运算结果赋值给变量 c。 注意,使用变量时不用加 $前缀,(( )) 会自动解析变量名。 |
a=$((1+6)b=$((a-1))c=$((a+b)) | 可以在 (( )) 前面加上$符号获取 (( )) 命令的执行结果,也即获取整个表达式的值。以 c=$((a+b)) 为例,即将 a+b 这个表达式的运算结果赋值给变量 c。 注意,如果 c=((a+b)) 这样的写 法是错误的,不加 $就不能取得表达式的结果。 |
| ((a>7 && b==c)) | (( )) 也可以进行逻辑运算,在 if 语句中常会使用逻辑运算。 |
| echo $((a+10)) | 需要立即输出表达式的运算结果时,可以在 (( )) 前面加$符号。 |
| ((a=3+5, b=a+10)) | 对多个表达式同时进行计算, 多表表达式使用","号隔开 |
注意: 符号之间有无空格都可以 , (( a = 1 + 6 )) 等价于 ((a=1+6))
需求
xxxxxxxxxx151# 计算1+6赋值给变量a23# 计算变量a-1赋值给变量b45# 计算变量a+变量b赋值给变量c67# 打印变量a,变量b, 变量c的值89# $赋值写法1011# (())多个表达式计算赋值1213# echo输出直接使用(())1415# (()) 用于逻辑表达式 在if中使用
calculatej2.sh脚本代码
xxxxxxxxxx3112# 计算1+6赋值给变量a3((a=1+6))45# 计算变量a-1赋值给变量b6((b=a-1))78# 计算变量a+变量b赋值给变量c9((c=a+b))1011# 打印变量a,变量b, 变量c的值12echo "a=${a},b=${b},c=${c}"1314# $赋值写法15a=$((1+6)) b=$((a-1)) c=$((a+b))16echo "a=${a},b=${b},c=${c}"1718# (())多个表达式计算赋值19((a=1+6,b=a-1,c=a+b))20echo "a=${a},b=${b},c=${c}"2122# echo输出直接使用(())23echo "1+6=$((1+6))"2425# (()) 用于逻辑表达式 在if中使用26if ((a>7 && b==c))27then28 echo "a>7 && b==c 成立"29else30 echo "a>7 && b==c 不成立"31fi
运行结果
let 命令和双小括号 (( )) 在数字计算方面功能一样. 但是没有(())功能强大, let只能用于赋值计算, 不能直接输出, 不可以条件判断一起使用
xxxxxxxxxx11let 赋值表达式注意
语法功能等价于
((表达式))多个表达式之间使用空格, 不是","号
对于类似
let a+b这样的写法,Shell 虽然计算了 a+b 的值,但却将结果丢弃, 如果echo let a+b会直接输出字符串a+b;若不想这样,可以使用let sum=a+b将 a+b 的结果保存在变量 sum 中。
输出建议使用(())
需求
xxxxxxxxxx41# 计算变量a-1赋值给变量b2# 计算变量a+变量b赋值给变量c3# 打印变量a,变量b, 变量c的值4# let多个表达式计算赋值
calculate3.sh脚本代码
xxxxxxxxxx1612# 计算1+6赋值给变量a3let a=1+645# 计算变量a-1赋值给变量b6let b=a-178# 计算变量a+变量b赋值给变量c9let c=a+b1011# 打印变量a,变量b, 变量c的值12echo "a=${a},b=${b},c=${c}"1314# let多个表达式计算赋值15let a=1+6 b=a-1 c=a+b16echo "a=${a},b=${b},c=${c}"
运行效果
和 (())、let 命令类似,$[] 也只能进行整数运算。但是只能对单个表达式的计算求值与输出
xxxxxxxxxx11$[表达式]
- $[] 会对
表达式进行计算,并取得计算结果- 表达式内部不可以赋值给变量
calculate4.sh脚本代码
xxxxxxxxxx1512# 计算1+6赋值给变量a3a=$[1+6]45# 计算变量a-1赋值给变量b6b=$[a-1]78# 计算变量a+变量b赋值给变量c9c=$[a+b]1011# 打印变量a,变量b, 变量c的值12echo "a=${a},b=${b},c=${c}"1314# 直接输出15echo "$[1+6],$[7-1],$[7+6]"
运行结果
Bash shell内置了对整数运算的支持,但是并不支持浮点运算,而 linux bc (basic calculator)命令可以很方便的进行浮点运算. bc命令是Linux简单的计算器,能进行进制转换与计算。能转换的进制包括十六进制、十进制、八进制、二进制等。可以使用的运算符号包括(+)加法、(-)减法、(*)乘法、(/)除法、(^)指数、(%)余数等
xxxxxxxxxx11bc [options] [参数]| 选项 | 说明 |
|---|---|
| -h | help,帮助信息 |
| -v | version,显示命令版本信息 |
| -l | mathlib, 使用标准数学库, 例如使用内置函数就需要使用这个参数 |
| -i | interactive, 强制交互 |
| -w | warn, 显示 POSIX 的警告信息 |
| -s | standard, 使用 POSIX 标准来处理 |
| -q | quiet, 不显示欢迎信息 |
默认使用bc命令后回车会有很多欢迎信息, 可以使用
bc -q回车后不会有欢迎信息
文件: 指定包含计算任务的文件。
创建task.txt文件, 编辑文件内容(一个计算表达式一行)
xxxxxxxxxx21108*67+12345258+2007*11执行命令
可以使用
quit命令退出bc
| 变量名 | 作 用 |
|---|---|
| scale | 指定精度,也即小数点后的位数, 对计算结果指定保留小数;默认为 0,也即不使用小数部分。 |
| ibase | 指定输入的数字的进制,默认为十进制。 |
| obase | 指定输出的数字的进制,默认为十进制。 |
| last 或者 . | 获取最近计算打印结果的数字 |
| 函数名 | 作用 |
|---|---|
| s(x) | 计算 x 的正弦值,x 是弧度值。 |
| c(x) | 计算 x 的余弦值,x 是弧度值。 |
| a(x) | 计算 x 的反正切值,返回弧度值。 |
| l(x) | 计算 x 的自然对数。 |
| e(x) | 求 e 的 x 次方。 |
| j(n, x) | 贝塞尔函数,计算从 n 到 x 的阶数。 |
通常在linux下bc当计算器用, 具体有3个用法
使用 bc -q 命令,回车即可, 直接进行计算器进行运算
退出bc使用 quit
在 Shell 脚本中,我们可以借助管道使用 bc 计算器。
直接进行bc的表达式计算输出
xxxxxxxxxx11echo "expression" | bc [options]"expression" 表达式必须复合bc命令要求的公式
"expression" 表达式里面可以引用shell变量
例如: Shell变量
a=2在表达式里面引用的语法:$a
将bc计算结果赋值给Shell变量
xxxxxxxxxx51# 第一种方式2var_name=`echo "expression" | bc [options]`34# 第二种方式5var_name=$(echo "expression" | bc [options])$() 与 `` 功能一样, 都是执行里面的命令
区别
`` 是所有linux系统支持的方式, 兼容性较好, 但是容易与引号产生混淆
$() 不是所有linux系统都支持的方式, 兼容性较差, 但是不容易产生混淆
引用shell变量进行计算
注意 b是bc中定义的新变量, 与shell变量没有任何关系, 所以不可以在shell中获取b变量
进制转换
将计算表达式输出给bc去执行, 特点类似于文件中输入,可以输入多行表达式, 更加清晰
xxxxxxxxxx151# 第一种方式2var_name=`bc [options] << EOF3第一行表达式14第二行表达式25...6EOF7`89# 第二种方式10var_name=$(bc [options] << EOF11第一行表达式112第二行表达式213...14EOF15)
var_name这是Shell变量的名字
bc执行bc的命令
EOF..EOF输入流的多行表达式含义: 将EOF中间多行表达式输入给到bc去执行, j将bc执行的结果给到Shell变量var_name
如果有大量的数学计算,那么使用输入重定向就比较方便,因为数学表达式可以换行,写起来更加清晰。
能够使用if条件语句进行条件判断
if条件判断逻辑控制语句
多行写法语法
xxxxxxxxxx41if 条件2then3 命令4fi可以将if语句放入一行语法
xxxxxxxxxx11if 条件; then 命令; fi
xxxxxxxxxx61if 条件2then3 命令4else5 命令6fixxxxxxxxxx131if 条件12then3 命令14elif 条件25then6 命令27elif 条件38then9 命令310……11else12 命令N13fi
需求
xxxxxxxxxx61提示"请输入你的考试成绩:" 接收用户输入一个成绩, 之后使用if else条件句判断2要求1: 小于 60 输出"不及格"3要求2: 大于等于70 并且 小于80 输出"中等"4要求3: 大于等于80 并且 小于90 输出"良好"5要求4: 大于等于90 并且 小于等于100 输出"优秀"6要求5: 以上不符合输出"成绩不合法"
control1.sh脚本代码
xxxxxxxxxx1512read -p "请输入你的考试成绩:" score3if (( $score < 60 )); then4 echo "不及格"5elif (( $score >= 60 && $score < 70 )); then6 echo "及格"7elif (( $score >= 70 && $score < 80 )); then8 echo "中等"9elif (( $score >= 80 && $score < 90 )); then10 echo "良好"11elif (( $score >= 90 && $score <= 100 )); then12 echo "优秀"13else14 echo "成绩不合法"15fi
(())是一种数学计算命令,它除了可以进行最基本的加减乘除运算,还可以进行大于、小于、等于等关系运算,以及与、或、非逻辑运算。当 a 和 b 相等时,(( $a == $b ))判断条件成立,进入 if,执行 then 后边的 echo 语句
运行效果
linux任何命令的的执行都会有一个退出状态, 无论是内置命令还是外部文件命令. 还是自定义的 Shell 函数,当它退出(运行结束)时,都会返回一个比较小的整数值给调用(使用)它的程序,这就是命令的退出状态
大多数命令状态0代表成功, 非0代表失败. 也有特殊的命令,比如 diff 命令用来比较两个文件的不同,对于“没有差别”的文件返回 0,对于“找到差别”的文件返回 1,对无效文件名返回 2
Shell 中,有多种方式取得命令的退出状态,其中 $? 是最常见的一种.
Shell if 语句使用逻辑运算符将多个退出状态组合起来,这样就可以一次判断多个条件了。
| 运算符 | 使用格式 | 说明 |
|---|---|---|
| && 或 -a | 条件1 && 条件2 | 逻辑与运算符,当 条件1 和 条件2 同时成立时, 整个表达式才成立。 如果检测到 条件1 的退出状态为 0, 就不会再检测 条件2 了,因为不管 条件2 的退出状态是什么, 整个表达式必然都是不成立的,检测了也是多此一举。 |
| || 或 -o | 条件1 || 条件2 | 逻辑或运算符,条件1 和 条件2 两个表 达式中只要有一个成立,整个表达式就成立。 如果检 测到 条件1 的退出状态为 1,就不会再检测 条件2 了,因为 不管 条件2 的退出状态是什么,整个表达式必然都是成立的, 检测了也是多此一举。 |
| ! | !条件 | 逻辑非运算符,相当于“取反”的效果。如果 条件 成立,那么整 个表达式就不成立;如果 条件 不成立,那么整个表达式就成立。 |
提示输入"请输入文件全名: "和"请输入数据:" 并接收文件名与数据
使用逻辑运算符判断满足2 条件 : 文件需要具有可写权限 和 输入的数据长度不为0
满足以上2个条件 将用户输入的 数据 写入到指定的文件中去
创建itheima.txt
xxxxxxxxxx11touch itheima.txtcontrol2.sh脚本文件代码
xxxxxxxxxx1112read -p "请输入文件全名: " filename3read -p "请输入数据:" data4if [ -w $filename -a -n $data ]5then6 echo $data7 echo $data > $filename8 echo "成功"9else10 echo "失败"11fitest命令用于对文件或字符串进行检测,
-w判断文件是否存在并且可写,-n用于检测字符串是否非空, 后续讲解.
$data > $filename其中>用于将内容输出到指定文件中去
运行结果
####
Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。
功能与[]一样
xxxxxxxxxx41if test 数字1 options 数字2 2then 3...4fioptions具体如下
| 参数 | 说明 |
|---|---|
| -eq | 等于则为真 |
| -ne | 不等于则为真 |
| -gt | 大于则为真 |
| -ge | 大于等于则为真 |
| -lt | 小于则为真 |
| -le | 小于等于则为真 |
control3.sh脚本代码
xxxxxxxxxx1712num1=1 num2=1 num3=23echo "num1=${num1},num2=${num2},num3=${num3}"45if test $num1 -eq $num26then7 echo 'num1和num2两个数相等!'8else9 echo 'num1和num2两个数不相等!'10fi1112if test $num2 -eq $num313then14 echo 'num2和num3两个数相等!'15else16 echo 'num2和num3两个数不相等!'17fi运行效果
| 参数 | 说明 |
|---|---|
| = 或 == | 等于, 等于返回0代表成功,否则返回1代表失败 |
| != | 不等于 |
\< | 小于 |
\> | 大于 |
| -z 字符串 | 字符串的长度为零则为真 |
| -n 字符串 | 字符串的长度不为零则为真 |
control4.sh脚本代码
xxxxxxxxxx32123str1="itheima" str2="itcast" str3=""4echo "str1=${str1},str2=${str2},str3=${str3}"56if test $str1 = $str27then8 echo 'str1和str2两个字符串相等'9else10 echo 'str1和str2两个字符串不相等'11fi1213if test $str1 \> $str214then15 echo 'str1大于str2'16else17 echo 'str1小于str2'18fi1920if test -z $str221then22 echo "str2字符串长度为0"23else24 echo "str2字符串长度不为0"25fi2627if test -z $str328then29 echo "str3字符串长度为0"30else31 echo "str3字符串长度不为0"32fi运行效果
| 参数 | 说明 |
|---|---|
| -e 文件名 | exists, 如果文件存在则为真 |
| -r 文件名 | read,如果文件存在且可读则为真 |
| -w 文件名 | write,如果文件存在且可写则为真 |
| -x 文件名 | execute,如果文件存在且可执行则为真 |
| -s 文件名 | string,如果文件存在且至少有一个字符则为真 |
| -d 文件名 | directory,如果文件存在且为目录则为真 |
| -f 文件名 | file,如果文件存在且为普通文件则为真 |
| -c 文件名 | character,如果文件存在且为字符型特殊文件则为真 |
| -b 文件名 | 如果文件存在且为块特殊文件则为真 |
查询control1.sh与control2.sh文件
control5.sh脚本代码
xxxxxxxxxx15123if test -w ./control1.sh4then5 echo '文件已存在并且可写!'6else7 echo '文件不存在或不可写!'8fi910if test -e ./control1.sh -a -e ./control2.sh11then12 echo '两个文件都存在!'13else14 echo '可能有一个或两个文件不存在'15fiShell提供了与( -a )、或( -o )、非( ! )三个逻辑操作符用于将测试条件连接起来,其优先级为:"!"最高,"-a"次之,"-o"最低, 语法
xxxxxxxxxx11test 条件1 -o 条件2 -a 条件3 ...
运行效果
Shell case语句为多选择语句。可以用case语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令;
当分支较多,并且判断条件比较简单时,使用 case in 语句就比较方便了。
xxxxxxxxxx171case 值 in2匹配模式1)3 命令14 命令25 ...6 ;;7匹配模式2)8 命令19 命令210 ...11 ;;12*)13 命令114 命令215 ...16 ;;17esac每一匹配模式必须以右括号结束。取值可以为变量或常数。匹配发现取值符合某一模式后,其间所有命令开始执行直至 ;;(类似break, 不可以替代否则语法报错)。取值将检测匹配的每一个模式。一旦模式匹配,则执行完匹配模式相应命令后不再继续其他模式。如果无一匹配模式,使用星号 * 捕获该值,再执行后面的命令。
case、in 和 esac 都是 Shell 关键字, esac就是case的反写在这里代表结束case
匹配模式: 可以是一个数字、一个字符串,甚至是一个简单正则表达式。
简单正则表达式支持如下通配符
| 格式 | 说明 |
|---|---|
| * | 表示任意字符串。 |
| [abc] | 表示 a、b、c 三个字符中的任意一个。比如,[15ZH] 表示 1、5、Z、H 四个字符中的任意一个。 |
| [m-n] | 表示从 m 到 n 的任意一个字符。比如,[0-9] 表示任意一个数字,[0-9a-zA-Z] 表示字母或数字。 |
| | | 表示多重选择,类似逻辑运算中的或运算。比如,abc | xyz 表示匹配字符串 "abc" 或者 "xyz"。 |
control6.sh脚本代码
xxxxxxxxxx2812read -p "请输入一个0~7的数字:" number3case $number in41)5 echo "星期一"6 ;;72)8 echo "星期二"9 ;;103)11 echo "星期三"12 ;;134)14 echo "星期四"15 ;;165)17 echo "星期五"18 ;;196)20 echo "星期六"21 ;;220|7)23 echo "星期日"24 ;;25*)26 echo "您输入的数字无效"27 ;; 28esac
运行效果
while用于循环执行一系列命令
多行写法
xxxxxxxxxx81while 条件2do3 命令14 命令25 ...6 continue; # 结束当前这一次循环, 进入下一次循环7 break; # 结束当前循环8done一行写法
xxxxxxxxxx11while 条件; do 命令; done;control7.sh脚本文件代码: 输出指定多少次的hello world
xxxxxxxxxx812read -p "请输入一个数字:" number3i=04while [[ $i < $number ]]5do6 echo "hello world"7 ((i++))8done运行效果
xxxxxxxxxx41while :2do3 command4done或
xxxxxxxxxx41while true2do3 command4done
until 也是循环结构语句, until 循环与 while 循环在处理方式上刚好相反, 循环条件为false会一致循环, 条件为true停止循环.
xxxxxxxxxx41until 条件2do3 命令4done条件如果返回值为1(代表false),则继续执行循环体内的语句,否则跳出循环。
control8.sh脚本代码
xxxxxxxxxx812read -p "请输入一个数字:" number3i=04until [[ ! $i < $number ]]5do6 echo "hello world"7 ((i++))8done运行效果
Shell支持for循环, 与其他编程语言类似.
多行写法
xxxxxxxxxx61for var in item1 item2 ... itemN2do3 命令14 命令25 ...6done一行写法
xxxxxxxxxx11for var in item1 item2 ... itemN; do 命令1; 命令2…; done;var是循环变量
item1 item2 ... itemN 是循环的范围
control9.sh脚本代码
xxxxxxxxxx512for i in 1 2 3 4 53do4 echo "hello world"5done
运行效果
多行写法
xxxxxxxxxx41for var in {start..end}2do3 命令4donestart: 循环范围的起始值,必须为整数
end: 循环范围的结束值, 必须为整数
一行写法
xxxxxxxxxx11for var in {start..end}; do 命令; done
循环1到5并打印
xxxxxxxxxx11for i in {1..5}; do echo $i; done效果
多行写法
xxxxxxxxxx41for((i=start;i<=end;i++))2do3 命令4done一行写法
xxxxxxxxxx11for((i=start;i<=end;i++)); do 命令; done
xxxxxxxxxx11for((;;)); do 命令; done
select in 循环用来增强交互性,它可以显示出带编号的菜单,用户输入不同的编号就可以选择不同的菜单,并执行不同的功能. select in 是 Shell 独有的一种循环,非常适合终端(Terminal)这样的交互场景, 其他语言没有;
xxxxxxxxxx41select var in menu1 menu2 ...2do3 命令4done注意: select 是无限循环(死循环),输入空值,或者输入的值无效,都不会结束循环,只有遇到 break 语句,或者按下 Ctrl+D 组合键才能结束循环。
执行命令过程中: 终端会输出
#?代表可以输入选择的菜单编号
脚本代码
xxxxxxxxxx812echo "你的爱好是什么?"3select hobby in "编程" "游戏" "篮球" "游泳"4do5 echo $hobby6 break7done8echo "你的爱好是:${hobby}"运行效果
脚本文件代码
xxxxxxxxxx2112echo "你的爱好是什么"3select hobby in "编程" "游戏" "篮球" "游泳"4do5 case $hobby in6 "编程")7 echo "编程,多敲代码"8 break9 ;;10 "游戏")11 echo "少玩游戏"12 break13 ;;14 "篮球"|"游泳")15 echo "运动有利健康"16 break17 ;;18 *)19 echo "输入错误,请重新输入"20 esac21done运行效果
Shell编程和其他编程语言一样, 有函数, 函数是由若干条shell命令组成的语句块,实现Shell脚本代码重用和模块化编程。
系统自带提供的函数, 可以直接使用.
basename函数用于获取文件名的函数, 根据给出的文件路径截取出文件名
xxxxxxxxxx11basename [string / pathname] [suffix] 根据根据指定字符串或路径名进行截取文件名, 比如: 根据路径"/one/two/aa.txt", 可以截取出aa.txt
suffix: 用于截取的时候去掉指定的后缀名.
从指定的文件绝对路径, 去除文件名,返回剩下的前缀目录路径
xxxxxxxxxx11dirname 文件绝对路径
开发人员可以通过自定义开发函数,实现代码重用.
xxxxxxxxxx101# 函数的定义2[ function ] funname ()3{4 命令5 [return 返回值]67}89# 调用函数10funname 传递参数1 传递参数2 ...
- 可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。
- 参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0~255)
必须在调用函数地方之前,先声明函数,shell脚本是逐行运行, 只要先运行了函数, 后面才可以时使用函数
文件脚本代码
xxxxxxxxxx812demo()3{4 echo "执行了函数"5}67# 调用函数8demo
运行效果
fun2.sh文件脚本代码
xxxxxxxxxx1312sum()3{4 echo "求两个数的和..."5 read -p "输入第一个数字: " n16 read -p "输入第二个数字: " n27 echo "两个数字分别为 $n1 和 $n2 "8 return $(($n1+$n2))9}1011# 调用函数12sum13echo "两个数字的和为: $? " # 获取函数返回值运行效果
在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1 表示第一个参数,$2 表示第二个参数...
其他参数介绍
| 参数处理 | 说明 |
|---|---|
| $# | 传递到脚本或函数的参数个数 |
| $* | 以一个单字符串显示所有向脚本传递的参数 |
| $$ | 脚本运行的当前进程ID号 |
| $! | 后台运行的最后一个进程的ID号 |
| $? | 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。 |
fun3.sh文件脚本代码
xxxxxxxxxx1212funParam(){3 echo "第一个参数为 $1 !"4 echo "第二个参数为 $2 !"5 echo "第十个参数为 $10 !"6 echo "第十个参数为 ${10} !"7 echo "第十一个参数为 ${11} !"8 echo "参数总数有 $# 个!"9 echo "作为一个字符串输出所有参数 $* !"10}11# 调用函数12funParam 1 2 3 4 5 6 7 8 9 10 22运行效果
函数和shell程序比较相似,区别在于: Shell 程序(内置命令和外部脚本文件), 外部脚本文件是在子Shell中运行, 会开启独立的进程运行 Shell函数在当前Shell的进程中运行
fun4.sh脚本文件代码
xxxxxxxxxx812demo(){3 echo "函数中打印当前进程ID:$$"4}56echo "当前脚本文件(Shell程序)打印当前进程ID:$$"7# 调用函数8demo运行效果
从键盘读取用户输入的数据,然后再把数据拿到Shell程序中使用;
Shell程序产生的数据,这些数据一般都是呈现到显示器上供用户浏览查看;
每个 Unix/Linux 命令运行时都会打开三个文件, 文件如下
| 文件名 | 类型 | 文件描述符(file description, fd) | 功能 |
|---|---|---|---|
| stdin | (standard input) 标准输入文件 | 0 | 获取键盘的输入数据 |
| stdout | (standard output) 标准输出文件 | 1 | 将正确数据输出到显示器上 |
| stderr | (standard error) 标准错误输出文件 | 2 | 将错误信息输出到显示器上 |
每个文件都有一个唯一的 文件描述符fd, 后面会通过唯一 文件描述符fd 操作对应的信息
Shell程序操作输入输出时用到这3个文件
这3个文件用于临时传输数据使用
标准输入是数据默认从键盘流向程序,如果改变了它的方向,数据就从其它地方流入,这就是输入重定向。
标准输出是数据默认从程序流向显示器,如果改变了它的方向,数据就流向其它地方,这就是输出重定向。
Linux Shell 重定向分为两种,一种输入重定向,一种是输出重定向;
输出重定向是指命令的结果不再输出到显示器上,而是输出到其它地方,一般是文件中。这样做的最大好处就是把命令的结果保存起来,当我们需要的时候可以随时查询。
| 命令 | 说明 |
|---|---|
| 命令 > file | 将正确数据重定向输出到 file 文件中, 覆盖方式 |
| 命令 < file | 将输入重定向从 file 文件中读取数据 |
| 命令 >> file | 将正确数据重定向输出到 file 文件中, 追加方式 |
| 命令 < file1 > file2 | 从file文件读取数据, 输出数据到file2文件中 |
| 命令 fd> file | 根据指定的文件描述符fd 将数据重定向输出到 file 文件中, 覆盖方式 |
| 命令 fd>> file | 根据指定的文件描述符fd 将数据重定向输出到 file 文件中, 追加方式 |
| 命令 > file fd1>& fd2 | 将 fd1 和 fd2 文件描述符合并 输出到文件。 |
| fd1<& fd2 | 将 fd1 和 fd2 文件描述符合并 从文件读取输入. |
| << tag | 读取终端输入数据, 将开始标记 tag 和结束标记 tag 之间的内容作为输入。 标记名tag可以任意 |
在输出重定向中,
>代表的是覆盖输出,>>代表的是追加输出。fd是文件描述符
0 通常是标准输入(STDIN),
1 是标准输出(STDOUT),
2 是标准错误输出(STDERR)。
fd> 或 fd>> 中间不可以有空格
创建文件redirect1.txt
xxxxxxxxxx11touch redirect1.txt执行who命令重定向输出到redirect1.txt文件中
xxxxxxxxxx11echo "itheima" >> redirect1.txt
预览错误消息
xxxxxxxxxx11ls java没有java目录所以报错
将错误消息输出到error.log文件中
xxxxxxxxxx11ls java 2> redirect2.txt2 是标准错误输出(STDERR), 注意
>覆盖方式输出
2>注意fd与>符号之间不能有空格
运行效果
将正确信息与错误信息都保存到一个文件中
xxxxxxxxxx11echo "itcast" > redirect2.txt 2>&1数字 1 代表正确输出的结果输出到文件中数字 2 代表错误结果输出到文件中
2>& 1将正确和错误都输出到文件中.2>&中间不能有空格, 写法有2种合并第一种写法:
2>& 1合并第二种写法:
2>&1
运行效果
Linux wc 命令可以用来对文本进行统计,包括单词个数、行数、字节数
xxxxxxxxxx11wc [options] [文件名]options有如下:
| 选项 | 含义 |
|---|---|
-c | character, 统计字节数 |
-w | word, 统计单词数 |
-l | line, 统计行数 |
统计文件redirect2.txt中数据行数
xxxxxxxxxx11wc -l < redirect2.txt运行效果
循环读取文件每一行数据
xxxxxxxxxx11while read str; do echo $str; done < redirect2.txt运行效果