这篇文章给大家介绍shell 脚本中有哪些常用的内置变量,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。
FUNCNAME
和LINENO
变量经常用于脚本的调试
FUNCNAME
表示当前函数的名字,作用范围仅限函数中使用,在函数外无值
LINENO
表示当前所在脚本中变量出现在的行号
PWD
表示当前目录, 对应于 pwd
命令
现有个脚本 a.sh
内容如下
#!/bin/bash
testa()
{
echo 'func='$FUNCNAME,$LINENO
}
testa
echo 'lineno:'$LINENO
echo 'xx:'$FUNCNAME
echo 'curpath:'$PWD
执行 ./a.sh
命令, 输出如下
[tt@ecs-centos-7 ~]$ ./a.sh
func=testa,6
lineno:12
xx:
curpath:/home/tt
在 testa
函数中 FUNCNAME
变量值是 testa
,也即函数名字,在函数外部无值
LINENO
变量无论是在函数中还是函数外,都表示当前所在的行号
这两个变量依次表示当前进程ID和父进程ID
现有 a.sh
脚本,内容如下
sleep 20
睡眠语句是为了让执行脚本进程暂缓退出,在另一个终端中验证输出的结果
#!/bin/bash
#set -u
echo 'cur pid:'$$
echo 'parent pid:'$PPID
sleep 20
在当前终端执行 ./a.sh
,结果如下
[tt@ecs-centos-7 ~]$ ./a.sh
cur pid:13095
parent pid:12982
在执行a.sh
的脚本进程退出之前,打开另一个终端,执行 ps -o pid,ppid,time,cmd -p 12982,13095
命令,结果如下
[tt@ecs-centos-7 ~]$ ps -o pid,ppid,time,cmd -p 12982,13095
PID PPID TIME CMD
12982 12981 00:00:00 -bash
13095 12982 00:00:00 /bin/bash ./a.sh
从上面的结果可以看出, 执行 ./a.sh
命令之后,$$ 变量表示的是 执行a.sh
脚本的进程ID 13095 ,而 12982 是它的父进程ID,也即是 PPID
变量的值,它是当前bash的实例
$#
表示从命令行传入脚本的参数数量
$0,$1,$2...$n
是从命令行传递到脚本的参数 $0
是脚本本身的名字$1
是第一个参数$2
是第二个参数,依此类推$n
是第n个参数
第十个参数及以后的参数必须要用大括号括起来,例如: ${10}、${11}、${12} 依次表示第十个变量、第十一个变量、第十二个变量
都表示位置参数,不过它们之间也有些不同点
使用 $*
时,如果加上双引号,即 $* 的形式,那所有位置的参数会被当作一个单词来处理,如果不包含双引号,即 $* 的形式,则每个位置的参数都被当作一个独立的单词来处理
而对于 $@
,无论是否加上双引号,每个位置的参数都被当作一个独立的单词来处理
现有c.sh
, 内容如下
#!/bin/bash
cnt=1
echo 'test 1111'
for var in "$*"
do
echo "arg$cnt="$var
let "cnt+=1"
done
echo
cnt=1
echo 'test 2222'
for var in $*
do
echo "arg$cnt="$var
let "cnt+=1"
done
echo
cnt=1
echo 'test 3333'
for var in "$@"
do
echo "arg$cnt="$var
let "cnt+=1"
done
echo
cnt=1
echo "test 4444"
for var in $@
do
echo "arg$cnt="$var
let "cnt+=1"
done
执行 ./c.sh 1 2 3
,结果如下
[root@ecs-centos-7 ~]# ./c.sh 1 2 3
test 1111
arg1=1 2 3test 2222
arg1=1
arg2=2
arg3=3test 3333
arg1=1
arg2=2
arg3=3test 4444
arg1=1
arg2=2
arg3=3
从上面的结果可以看出,对于 $* 来说,加了双引号之后所有位置参数就会被视为一个单词
对于 $@ 来说,是否加双引号,结果都是一样的
所以,仅在使用双引号时,$* 和 $@ 才会有差异
命令、函数或者脚本的退出状态,在判断命令的执行结果或者函数的调用结果时很有用处
现有 e.sh
和 f.sh
测试脚本
e.sh 脚本
#!/bin/bash
test_func()
{
if [[ $1 -eq 10 ]]; then
return 5
fi
return 6
}
if [ $# -ge 1 ]; then
name="$1"
shift 1
$name "$@"
fi
f.sh 脚本
#!/bin/bash
sh e.sh test_func 3
echo 'exit code1:'$?
sh e.sh test_func 10
echo 'exit code2:'$?
test -f $PWD/xx.txt
echo 'exit code3:'$?
test -f $PWD/e.sh
echo 'exit code4:'$?
执行 ./f.sh
命令,结果如下
[root@ecs-centos-7 ~]# ./f.sh
exit code1:6
exit code2:5
exit code3:1
exit code4:0
脚本 e.sh
中 test_func
函数功能是:当参数等于10时,退出状态为 5,否则为 6
sh e.sh test_func 3
命令会调用 e.sh
脚本中的 test_func
函数,传入参数是 3,所以退出状态为 6,同理可知, sh e.sh test_func 10
命令的退出状态是 5
在Linux中,命令执行成功,退出状态为 0 ,失败则为非 0
test -f $PWD/xx.txt
命令是检查当前目录是否存在 xx.txt
文件,因当前目录并不存在 xx.txt
,所以命令执行失败,退出状态为非 0
由于e.sh
存在于当前目录下,所以 test -f $PWD/e.sh
命令执行成功,退出状态为 0
此变量用于 Bash 识别字符串或单词边界,默认值是空格,脚本中根据需要可以修改此变量的值
现有 b.sh
脚本,内容如下
#!/bin/bash
va="a:b:c"
vb="x-y-z"
vc="e,f,g"
IFS=":"
echo 'va:'$va
echo 'vb:'$vb
echo 'vc:'$vc
echo
IFS="-"
echo 'va:'$va
echo 'vb:'$vb
echo 'vc:'$vc
echo
IFS=","
echo 'va:'$va
echo 'vb:'$vb
echo 'vc:'$vc
执行 ./b.sh
结果如下
[tt@ecs-centos-7 ~]$ ./b.sh
va:a b c
vb:x-y-z
vc:e,f,gva:a:b:c
vb:x y z
vc:e,f,gva:a:b:c
vb:x-y-z
vc:e f g
从结果可以看出,当 $IFS
为 :
时,字符串 "a:b:c"
被解析成 a b c
当 $IFS
为 -
时,字符串 "x-y-z"
被解析成 x y z
当 $IFS
为 ,
时,字符串 "e,f,g"
被解析成 e f g
$HOME、$USER、$UID、$GROUPS
HOME: 用户home目录
USER: 当前用户名
UID: 当前用户ID
GROUPS: 当前用户组ID
[tt@ecs-centos-7 ~]$ echo $HOME
/home/tt
[tt@ecs-centos-7 ~]$ echo $USER
tt
[tt@ecs-centos-7 ~]$ echo $UID
1003
[tt@ecs-centos-7 ~]$ echo $GROUPS
1003
这些变量都表示系统硬件
[tt@ecs-centos-7 ~]$ echo $HOSTTYPE
x86_64
[tt@ecs-centos-7 ~]$ echo $MACHTYPE
x86_64-redhat-linux-gnu
[tt@ecs-centos-7 ~]$ echo $OSTYPE
linux-gnu
关于shell 脚本中有哪些常用的内置变量就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。