@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 文件名
:如果文件存在且为块特殊文件则为真
cd /bin
if test -e ./bash
then
echo '文件已存在!'
else
echo '文件不存在!'
fi
输出结果:
代码语言:text复制文件已存在!
另外,Shell 还提供了与( -a )、或( -o )、非( ! )三个逻辑操作符用于将测试条件连接起来,其优先级为: !
最高, -a
次之, -o
最低。例如:
cd /bin
if test -e ./notFile -o -e ./bash
then
echo '至少有一个文件存在!'
else
echo '两个文件都不存在'
fi
输出结果:
代码语言:txt复制至少有一个文件存在!