Shell编程从看懂到看开③(函数、echo、printf、test)

2022-12-10 17:16:40 浏览数 (1)

@TOC

函数

自定义函数

linux shell 可以用户定义函数,然后在shell脚本中可以随便调用。

shell中函数的定义格式如下:

代码语言:text复制
[ function ] funname [()]

{

    action;

    [return int;]

}

注意:

  • 可以带function fun() 定义,也可以直接fun() 定义,不带任何参数
  • ==必须在调用函数地方之前,先声明函数==,shell 脚本是逐行运行。不会像其它语言一样先编译
  • 函数返回值,只能通过$?系统变量获得,可以显示加return 返回,如果不加,将以最后一条命令运行结果,作为返回值。return的返回值只能是0~255之间的一个整数
  • 调用函数仅使用其函数名即可,不需要括号

接下来我们使用函数完成两数的加和:

无return版:

在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述

有return版:

在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述

$? 仅对其上一条指令负责,一旦函数返回后其返回值没有立即保存入参数,那么其返回值将不再能通过 $? 获得。

函数参数

在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数...

带参数的函数示例:

代码语言:text复制
unWithParam(){
    echo "第一个参数为 $1 !"
    echo "第二个参数为 $2 !"
    echo "第十个参数为 $10 !"
    echo "第十个参数为 ${10} !"
    echo "第十一个参数为 ${11} !"
    echo "参数总数有 $# 个!"
    echo "作为一个字符串输出所有参数 $* !"
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73

输出结果:

代码语言:text复制
第一个参数为 1 !
第二个参数为 2 !
第十个参数为 10 !
第十个参数为 34 !
第十一个参数为 73 !
参数总数有 11 个!
作为一个字符串输出所有参数 1 2 3 4 5 6 7 8 9 34 73 !

注意,$10 不能获取第十个参数,获取第十个参数需要${10}。当n>=10时,需要使用${n}来获取参数。

系统函数

basename

==基本语法==

代码语言:text复制
basename [string / pathname] [suffix] (功能描述:basename 命令会删掉所有的前缀包括最后一个(‘/’)字符,然后将字符串显示出来。

basename 可以理解为取路径里的文件名称

选项:

suffix 为后缀,如果 suffix 被指定了,basename 会将 pathname 或 string 中把 suffix 去掉。

例如:

代码语言:text复制
[root@hadoop101 shells]$ basename /home/atguigu/banzhang.txt
banzhang.txt
[root@hadoop101 shells]$ basename /home/atguigu/banzhang.txt .txt
banzhang

dirname

==基本语法==

代码语言:text复制
dirname 文件绝对路径 (功能描述:从给定的包含绝对路径的文件名中去除文件名(非目录的部分),然后返回剩下的路径(目录的部分))

dirname 可以理解为取文件路径的绝对路径名称

例如:

获取 banzhang.txt 文件的路径。

代码语言:txt复制
[root@hadoop101 ~]$ dirname /home/root/banzhang.txt
/home/atguigu

Shell echo 命令

Shell 的 echo 指令与 PHP 的 echo 指令类似,==都是用于字符串的输出==。命令格式:

代码语言:txt复制
echo string

你可以使用echo实现更复杂的输出格式控制。

==显示普通字符串==

代码语言:txt复制
echo "It is a test"

这里的双引号完全可以省略,以下命令与上面实例效果一致:

代码语言:txt复制
echo It is a test

==显示转义字符==

代码语言:txt复制
echo ""It is a test""

结果将是:

代码语言:txt复制
"It is a test"

同样,双引号也可以省略

==显示变量==

read 命令从标准输入中读取一行,并把输入行的每个字段的值指定给 shell 变量

代码语言:txt复制
#!/bin/sh
read name 
echo "$name It is a test"

以上代码保存为 test.sh,name 接收标准输入的变量,结果将是:

代码语言:txt复制
[root@www ~]# sh test.sh
OK                     #标准输入
OK It is a test        #输出

==显示换行==

代码语言:txt复制
echo -e "OK! n"       # -e 开启转义
echo "It is a test"

输出结果:

代码语言:txt复制
OK!

It is a test

==显示不换行==

代码语言:txt复制
#!/bin/sh
echo -e "OK! c"       # -e 开启转义 c 不换行
echo "It is a test"

输出结果:

代码语言:txt复制
OK! It is a test

==显示结果定向至文件==

代码语言:text复制
echo "It is a test" > myfile

==原样输出字符串,不进行转义或取变量(用单引号)==

代码语言:text复制
echo '$name"'

输出结果

代码语言:text复制
$name"

==显示命令执行结果==

代码语言:txt复制
echo `date`

注意: 这里使用的是反引号 `, 而不是单引号 '。

结果将显示当前日期

代码语言:txt复制
Thu Jul 24 10:08:46 CST 2014

Shell printf 命令

printf 命令模仿 C 程序库(library)里的 printf() 程序。

printf 由 POSIX 标准所定义,因此使用 printf 的脚本比使用 echo 移植性好。

printf 使用引用文本或空格分隔的参数,外面可以在 printf 中使用格式化字符串,还可以制定字符串的宽度、左右对齐方式等。默认的 printf 不会像 echo 自动添加换行符,我们可以手动添加 n。

printf 命令的语法:

代码语言:text复制
printf  format-string  [arguments...]

参数说明:

  • format-string: 为字符串控制格式
  • arguments: 为参数列表

例如:

代码语言:text复制
#!/bin/bash

printf "%-10s %-8s %-4sn" 姓名 性别 体重kg  
printf "%-10s %-8s %-4.2fn" 郭靖 男 66.1234
printf "%-10s %-8s %-4.2fn" 杨过 男 48.6543
printf "%-10s %-8s %-4.2fn" 郭芙 女 47.9876

输出结果:

代码语言:text复制
姓名     性别   体重kg
郭靖     男      66.12
杨过     男      48.65
郭芙     女      47.99

%s %c %d %f 都是格式替代符,%s 输出一个字符串,%d 整型输出,%c 输出一个字符,%f 输出实数,以小数形式输出。

%-10s 指一个宽度为 10 个字符(- 表示左对齐,没有则表示右对齐),任何字符都会被显示在 10 个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。

%-4.2f 指格式化为小数,其中 .2 指保留2位小数。

我们再来看一个脚本:

代码语言:text复制
#!/bin/bash

# format-string为双引号
printf "%d %sn" 1 "abc"

# 单引号与双引号效果一样
printf '%d %sn' 1 "abc"

# 没有引号也可以输出
printf %s abcdef

# 格式只指定了一个参数,但多出的参数仍然会按照该格式输出,format-string 被重用
printf %s abc def

printf "%sn" abc def

printf "%s %s %sn" a b c d e f g h i j

# 如果没有 arguments,那么 %s 用NULL代替,%d 用 0 代替
printf "%s and %d n"

执行脚本,输出结果如下所示:

在这里插入图片描述在这里插入图片描述

==printf 的转义序列==

在这里插入图片描述在这里插入图片描述

Shell test 命令

Shell中的 test 命令用于检查某个条件是否成立,它可以进行如下三个方面的测试:

  • 数值测试
  • 字符测试
  • 文件测试

数值测试

  • -eq:等于则为真
  • -ne:不等于则为真
  • -gt:大于则为真
  • -ge:大于等于则为真
  • -lt:小于则为真
  • -le:小于等于则为真

例如:

代码语言:text复制
num1=100
num2=100
if test $[num1] -eq $[num2]
then
    echo '两个数相等!'
else
    echo '两个数不相等!'
fi

结果:

代码语言:text复制
两个数相等!

字符串测试

  • =:等于则为真
  • !=:不相等则为真
  • -z 字符串:字符串的长度为零则为真
  • -n 字符串:字符串的长度不为零则为真

例如:

代码语言:text复制
num1="ru1noob"
num2="runoob"
if test $num1 = $num2
then
    echo '两个字符串相等!'
else
    echo '两个字符串不相等!'
fi

结果:

代码语言:text复制
两个字符串不相等!

文件测试

  • -e 文件名:如果文件存在则为真
  • -r 文件名:如果文件存在且可读则为真
  • -w 文件名:如果文件存在且可写则为真
  • -x 文件名:如果文件存在且可执行则为真
  • -s 文件名:如果文件存在且至少有一个字符则为真
  • -d 文件名:如果文件存在且为目录则为真
  • -f 文件名:如果文件存在且为普通文件则为真
  • -c 文件名:如果文件存在且为字符型特殊文件则为真
  • -b 文件名:如果文件存在且为块特殊文件则为真
代码语言:text复制
cd /bin
if test -e ./bash
then
    echo '文件已存在!'
else
    echo '文件不存在!'
fi

输出结果:

代码语言:text复制
文件已存在!

另外,Shell 还提供了与( -a )、或( -o )、非( ! )三个逻辑操作符用于将测试条件连接起来,其优先级为: ! 最高, -a 次之, -o 最低。例如:

代码语言:text复制
cd /bin
if test -e ./notFile -o -e ./bash
then
    echo '至少有一个文件存在!'
else
    echo '两个文件都不存在'
fi

输出结果:

代码语言:txt复制
至少有一个文件存在!

0 人点赞