今天主要学习一下Shell里的函数和几个常用的命令,首先是函数,格式比较简单,看个例子就明白了:
$ func(){
> echo "Hello World!"
> }
Huper@DESKTOP-AT9MCJI ~
$ func
Hello World!
可以看出有一点不同就是这个小括号并不是用来接受参数的,所以调用函数的时候直接使用函数名就行了,那么如何向Shell里的函数传递参数呢?先看个例子:
$ func(){
> echo "para 0 : $0"
> echo "para 1 : $1"
> echo "para 2 : $2"
> echo "all $# paras"
> }
Huper@DESKTOP-AT9MCJI ~
$ func 1 2
para 0 : bash
para 1 : 1
para 2 : 2
all 2 paras
也就是说类似脚本文件,这里的参数是命令行在调用函数的时候进行检测的,并且注意到第0个参数是程序名是bash。Shell里的函数同样允许有返回值,来看个例子:
Huper@DESKTOP-AT9MCJI ~
# 精简写法,注意 } 之前的 ;,并且这里在 (()) 之前必须有引用。
$ plus(){ return $(($1+$2)); }
$ plus 1 2
Huper@DESKTOP-AT9MCJI ~
# $?表示最后命令的退出状态,存有返回值
$ echo $?
3
函数差不多就这么多,下面讲下hell里常用的三个命令echo
,printf
和test
。echo
命令之前已经用过很多了,现在来看下它的一些其他功能:
# wrong use
Huper@DESKTOP-AT9MCJI ~
$ echo "\n info \n"
\n info \n
# add -e before
Huper@DESKTOP-AT9MCJI ~
$ echo -e "\n info \n"
info
# no need to add -e
$ echo "\"It is a test\""
"It is a test"
# 重定向结果至文件,可以不留白
$ echo "added some info" > shelltest.sh
# 单引号不支持转义
$ echo '123 \n'
123 \n
# 调用date命令并输出结果
$ echo `date`
Tue Dec 26 11:23:15 2017
然后是类似c语言中的格式化输出命令printf
:
$ printf "%-10s %-10s %-4.3f" 123 456 0.123456
123 456 0.123
# 单引号也行,并且支持转义
$ printf '%s\n%s' abc def
# 不带引号不行,但不支持转义
$ printf %s\n%s abc def
# 给定参数多于格式化参数(重用)
$ printf %s abc def
abc
def
# 格式化参数多于给定参数(0或NULL)
$ printf "%s and %d \n"
and 0
最后是test
命令,常和if
一起使用,可以检查某个条件是否成立,事实上test命令就相当于[]
:
$ if test $a -lt $b; then echo "equal"; fi
# 可以直接在[]内部进行计算,但是功能比较首先,推荐使用(())
$ if test $[a+b] -lt $b; then echo "equal"; fi
test
用在文件测试里比较多,常用于测试文件的参数有以下:
参数 | 说明 |
---|---|
-e 文件名 | 如果文件存在则为真 |
-r 文件名 | 如果文件存在且可读则为真 |
-w 文件名 | 如果文件存在且可写则为真 |
-x 文件名 | 如果文件存在且可执行则为真 |
-s 文件名 | 如果文件存在且至少有一个字符则为真 |
-d 文件名 | 如果文件存在且为目录则为真 |
-f 文件名 | 如果文件存在且为普通文件则为真 |
-c 文件名 | 如果文件存在且为字符型特殊文件则为真 |
-b 文件名 | 如果文件存在且为块特殊文件则为真 |
举例说明:
# 可以使用 -a -o ! 三个逻辑操作来连接普通操作
$ if test -e ./shelltest.sh -o -e ./bash; then echo 'one!'; else echo 'all!'; fi