Shell编程从看懂到看开③(函数、echo、printf、test)
@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
banzhangdirname==基本语法==
代码语言:text复制dirname 文件绝对路径 (功能描述:从给定的包含绝对路径的文件名中去除文件名(非目录的部分),然后返回剩下的路径(目录的部分))dirname 可以理解为取文件路径的绝对路径名称
例如:
获取 banzhang.txt 文件的路径。
代码语言:txt复制[root@hadoop101 ~]$ dirname /home/root/banzhang.txt
/home/atguiguShell 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 2014Shell 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 %-4s\n" 姓名 性别 体重kg
printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234
printf "%-10s %-8s %-4.2f\n" 杨过 男 48.6543
printf "%-10s %-8s %-4.2f\n" 郭芙 女 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 %s\n" 1 "abc"
# 单引号与双引号效果一样
printf '%d %s\n' 1 "abc"
# 没有引号也可以输出
printf %s abcdef
# 格式只指定了一个参数,但多出的参数仍然会按照该格式输出,format-string 被重用
printf %s abc def
printf "%s\n" abc def
printf "%s %s %s\n" 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复制至少有一个文件存在!
