Shell编程学习(二)

88 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情

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=200
num2=200
if [ $[num1] -eq $[num2] ]
then
    echo '两个数相等!'
else
    echo '两个数不相等!'
fi

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

a=10
b=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

blog.csdn.net/qq_41880412…

12、shell 控制流

1)if判断流

if else fi 语法格式如下:

if condition
then
    command1 
    command2
    ...
    commandN 
fi

测试1:

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

测试2:

a=5
b=6
if [ $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 ... itemN
do
    command1
    command2
    ...
    commandN
done

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

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

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

for str in hello chuan chuan
do
    echo $str
done

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

echo "输入一个数:"
read num
for ((  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 condition
do
    command
done

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

int=1
while(( $int<=6 ))
do
    echo $int
    let "int++"
done

4)until 循环

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

until condition
do
    command
done

举个例子:使用 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 a
case $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 "函数开始执行"
demoFun
echo "-函数执行完毕"

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

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

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

$$

Shell本身的PIDProcessID,即脚本运行的当前 进程ID号)

$!

Shell最后运行的后台ProcessPID(后台运行的最后一个进程的 进程ID号)

$?

最后运行的命令的结束代码(返回值)即执行上一个指令的返回值 (显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误)

$-

显示shell使用的当前选项,与set命令功能相同

$*

所有参数列表。如"$*"用「"」括起来的情况、以"$1 $2$n"的形式输出所有参数,此选项参数可超过9个。

$@

所有参数列表。如"$@"用「"」括起来的情况、以"$1" "$2""$n" 的形式输出所有参数。

$@$*类似,但是可以当作数组用

$#

添加到Shell的参数个数

$0

Shell本身的文件名

$1$n

添加到Shell的各参数值。$1是第1参数、$2是第2参数…。

测试脚本

#!/bin/sh
echo "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
    document
delimiter

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

注意:

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

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

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

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

#!/bin/bash
# author:菜鸟教程
# url:www.runoob.com

cat << EOF
欢迎来到
菜鸟教程
www.runoob.com
EOF

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

欢迎来到
菜鸟教程
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> 是一体的时候才表示错误输出。