写点什么

Shell 编程学习(二)

作者:Studying_swz
  • 2022 年 9 月 25 日
    天津
  • 本文字数:4385 字

    阅读完需:约 14 分钟

Shell编程学习(二)

11、Shell test 命令


test 是 shell 内置命令,用来检测某个条件是否成立 test 通常和 if 语句一起使用,并且大部分 if 语句都依赖 test,shell test 命令的用法有两种:

第一种:

test expression #当 test 判断 expression 成立时,退出状态为 0,否则为非 0 值

第二种:

[ expression ] #[ ]和 expression 的两边都有空格,这个空格是必须的,否则会导致语法错误

#[ ]写法更简洁,使用频率更高


1)数值测试

参数和说明如下:

-eq 等于则为真

-ne 不等于则为真

-gt 大于则为真

-ge 大于等于则为真

-lt 小于则为真

-le 小于等于则为真

演示一个参数如下:

num1=200num2=200if [ $[num1] -eq $[num2] ]then    echo '两个数相等!'else    echo '两个数不相等!'fi
复制代码


代码中的 [] 执行基本的算数运算,例如:

a=10b=10
result=$[a+b] # 注意等号两边不能有空格echo "result結果为: $result"
复制代码


2)字符串测试

参数如下:

=   等于则为真!=  不相等则为真<   比较两者的大小> 	比较两者的大小-z 字符串  字符串的长度为零则为真-n 字符串  字符串的长度不为零则为真
复制代码


a)比较字符串是否相等:

num1="chuan"num2="chuan"if [ $num1 = $num2 ]then    echo '两个字符串相等!'else    echo '两个字符串不相等!'fi
复制代码


b)比较字符串的大小:

  • 字符串大小的比较遵循字典顺序,规则如下:

  • 1.如果第一个字符串是第二个字符串的前缀,那么第一个小(比如 a 小于 about)

  • 2.从字符串的开头比较,按照字母顺序,a 比 b 小(比如 about 小于 ball)

  • 3.如果第一个字符相同,再比较第二个(比如 about 小于 above)

方法:

[ str1 < str2 ]

[ str1 > str2 ]


c)比较字符串的长度

  • 没有被定义的字符串长度默认为 0

方法:

[ -n str1 ] #检查str1的长度是否非0

[ -z str1 ] #检查str1的长度是否为0


3)文件测试

参数:


-e 文件名  如果文件存在则为真-r 文件名  如果文件存在且可读则为真-w 文件名  如果文件存在且可写则为真-x 文件名  如果文件存在且可执行则为真-s 文件名  如果文件存在且至少有一个字符则为真-d 文件名  如果文件存在且为目录则为真-f 文件名  如果文件存在且为普通文件则为真-c 文件名  如果文件存在且为字符型特殊文件则为真-b 文件名  如果文件存在且为块特殊文件则为真-O file		检查file是否存在并属当前用户所有-G file		检查file是否存在并且默认组与当前用户相同file1 -nt file2 检查file1是否比file2新file1 -ot file2 检查file1是否比file2旧
复制代码

举一个例子:

if  [ -e ./test1.sh ]then    echo '文件已存在!'else    echo '文件不存在!'fi
复制代码

https://blog.csdn.net/qq_41880412/article/details/104331970


12、shell 控制流


1)if 判断流

if else fi 语法格式如下:

if conditionthen    command1     command2    ...    commandN fi
复制代码

测试 1:

a=5b=6if [ $a -gt $b ]then        echo '大于'else            echo '小于'fi
复制代码

测试 2:

a=5b=6if [ $a==$b ]then        echo '等於'elif [ $a -gt $b ]then   echo "a 大于 b"elif [ $a -lt $b ]then   echo "a 小于 b"else   echo "没有符合的条件"fi
复制代码


2)for 循环

  • 1.for 循环在实际生成中应用非常多,避免人工重复的去操作某个事情

  • 2.for 循环中的列表支持正则表达式

  • 3.for 循环中使用(()),双括号内支持 C 语言的命令

  • 4.for 循环中的变量,只是循环去取值列表中取值,然后进行 do 操作,所以取值列表中的参数个数,决定了循环的次数

语法:

for var in item1 item2 ... itemNdo    command1    command2    ...    commandNdone
复制代码

测试 1:顺序输出当前列表中的数字

for a in 1 2 3 4 5do    echo "值依次爲: $a"done
复制代码

测试 2:顺序输出字符串中的字符

for str in hello chuan chuando    echo $strdone
复制代码

测试 3:打印任意数的乘法表

echo "输入一个数:"read numfor ((  i=1;i<=$num;i++  ))do   for ((  j=1;j<=$num;j++  ))   do      [  $j  -le  $i  ]  &&  echo -n "${i}*${j}=$((i*j))      "    #判断j是否小于i,当j大于i时不输出,输出不换行,末尾加一个制表符   done   echo ""           #输出一个换行符                done
复制代码


3)while 循环

语法格式:

while conditiondo    commanddone
复制代码

测试 1,依次输出 1 到 6:

int=1while(( $int<=6 ))do    echo $int    let "int++"done
复制代码


4)until 循环

until 循环执行一系列命令直至条件为 true 时停止。until 循环与 while 循环在处理方式上刚好相反。 语法为:

until conditiondo    commanddone
复制代码

举个例子:使用 until 命令来输出 0 ~ 6 的数字

a=0
until [ ! $a -lt 6 ]do echo $a a=`expr $a + 1`done
复制代码


5)case ... esac


case ... esac 为多选择语句,与 C 语言中的 switch ... case 类似,每个 case 分支用右圆括号开始,用两个分号 ;; 表示 break,即执行结束. 语法为:

case 值 in模式1)    command1    command2    ...    commandN    ;;模式2)    command1    command2    ...    commandN    ;;esac
复制代码


测试:提示输入 1 到 4,与每一种模式进行匹配

echo '输入 1 到 4 之间的数字:'echo '你输入的数字为:'read acase $a in    1)  echo '你选择了 1'    ;;    2)  echo '你选择了 2'    ;;    3)  echo '你选择了 3'    ;;    4)  echo '你选择了 4'    ;;    *)  echo '你没有输入 1 到 4 之间的数字'    ;;esac
复制代码

6)跳出循环

break break 命令允许跳出所有循环(终止执行后面的所有循环)。

continue continue 命令与 break 命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环。

注:所有语言这个都是通用的,就不多说了。


13、Shell 函数

直接来看一个 demo 函数:


demoFun(){    echo "測試一下我的函數!"}echo "函数开始执行"demoFunecho "-函数执行完毕"
复制代码

定义一个带有 return 语句的函数: 代码为:

add(){    echo "这个函数为求两个函数之和.."    echo "输入第一个数字: "    read aNum    echo "输入第二个数字: "    read bNum    echo "两个数字分别为 $aNum 和 $bNum !"    return $(($aNum+$bNum))}addecho "输入的两个数字之和为 $? !"
复制代码


引: Shell 脚本中 $0、$?、$!、$$、$*、$#、$@等的意义说明?

$$
Shell本身的PID(ProcessID,即脚本运行的当前 进程ID号)
$!
Shell最后运行的后台Process的PID(后台运行的最后一个进程的 进程ID号)
$?
最后运行的命令的结束代码(返回值)即执行上一个指令的返回值 (显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误)
$-
显示shell使用的当前选项,与set命令功能相同
$*
所有参数列表。如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数,此选项参数可超过9个。
$@
所有参数列表。如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。
$@ 跟$*类似,但是可以当作数组用
$#
添加到Shell的参数个数
$0
Shell本身的文件名
$1~$n
添加到Shell的各参数值。$1是第1参数、$2是第2参数…。
复制代码

测试脚本

#!/bin/shecho "number:$#"echo "scname:$0"echo "first :$1"echo "second:$2"echo "argume:$@"
复制代码

结果:

number:2

scname:./variable

first: aa

second:bb

argume:aa bb


14、Shell 输入/输出重定向

相关参数如下:

command > file  将输出重定向到 file。command < file  将输入重定向到 file。command >> file 将输出以追加的方式重定向到 file。n > file    将文件描述符为 n 的文件重定向到 file。n >> file   将文件描述符为 n 的文件以追加的方式重定向到 file。n >& m  将输出文件 m 和 n 合并。n <& m  将输入文件 m 和 n 合并。<< tag  将开始标记 tag 和结束标记 tag 之间的内容作为输入。
复制代码


1)输出重定向

将输出重定向到 wen 文件夹:

这样的重定向有一个缺点就是会覆盖原来的内容,如果你不想覆盖原来的内容,你可以使用:

command >> file 将输出以追加的方式重定向到 file。
复制代码


2)输入重定向

和输出重定向一样,Unix 命令也可以从文件获取输入,语法为:

command1 < file1
复制代码


这样,本来需要从键盘获取输入的命令会转移到文件读取内容。

注意:输出重定向是大于号(>),输入重定向是小于号(<)。

users 文件:

菜鸟教程:www.runoob.com菜鸟教程:www.runoob.com
复制代码

接着以上实例,我们需要统计 users 文件的行数,执行以下命令:

$ wc -l users       2 users
复制代码

也可以将输入重定向到 users 文件:

wc -l < users       2 
复制代码

注意:上面两个例子的结果不同:第一个例子,会输出文件名第二个不会因为它仅仅知道从标准输入读取内容。

引入:同时替换输入和输出,执行 command1,从文件 infile 读取内容,然后将输出写入到 outfile 中。

command1 < infile > outfile
复制代码

3)重定向深入讲解

一般情况下,每个 Unix/Linux 命令运行时都会打开三个文件:

  • 标准输入文件(stdin):stdin 的文件描述符为 0,Unix 程序默认从 stdin 读取数据。

  • 标准输出文件(stdout):stdout 的文件描述符为 1,Unix 程序默认向 stdout 输出数据。

  • 标准错误文件(stderr):stderr 的文件描述符为 2,Unix 程序会向 stderr 流中写入错误信息。

默认情况下,command > file 将 stdout 重定向到 file,command < file 将 stdin 重定向到 file。

如果希望 stderr 重定向到 file,可以这样写:

$ command 2>file
复制代码

2 表示标准错误文件(stderr)。

如果希望将 stdout 和 stderr 合并后重定向到 file,可以这样写:

$ command > file 2>&1
或者
$ command >> file 2>&1
复制代码


4)Here Document(了解)


Here Document 是 Shell 中的一种特殊的重定向方式,用来将输入重定向到一个交互式 Shell 脚本或程序。 语法为;

command << delimiter    documentdelimiter
复制代码

它的作用是将两个 delimiter 之间的内容(document) 作为输入传递给 command。

注意:

  • 结尾的 delimiter 一定要顶格写,前面不能有任何字符,后面也不能有任何字符,包括空格和 tab 缩进。

  • 开始的 delimiter 前后的空格会被忽略掉。

在命令行中通过 wc -l 命令计算 Here Document 的行数:

$ wc -l << EOF    欢迎来到    菜鸟教程    www.runoob.comEOF3          # 输出结果为 3 行$
复制代码

我们也可以将 Here Document 用在脚本中,例如:

#!/bin/bash# author:菜鸟教程# url:www.runoob.com
cat << EOF欢迎来到菜鸟教程www.runoob.comEOF
复制代码

执行以上脚本,输出结果:

欢迎来到菜鸟教程www.runoob.com
复制代码

5)/dev/null 文件

如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null,/dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。但是 /dev/null 文件非常有用,将命令的输出重定向到它,会起到"禁止输出"的效果。


如果希望屏蔽 stdout 和 stderr,可以这样写:

$ command > /dev/null 2>&1
复制代码

注意:0 是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)。

这里的 2 和 > 之间不可以有空格,2> 是一体的时候才表示错误输出。


发布于: 刚刚阅读数: 3
用户头像

Studying_swz

关注

还未添加个人签名 2020.12.23 加入

还未添加个人简介

评论

发布
暂无评论
Shell编程学习(二)_Shell_Studying_swz_InfoQ写作社区