Shell编程-03-Shell中的特殊变量和扩展变量
特殊变量
在Shell中的特殊变量主要分别两种位置参数变量、状态变量两种。
位置参数变量
Shell中的位置参数变量主要是指$0、$1、$#等,主要用于从命令行、函数或脚本执行等地方传递参数。详细说明如下所示:
- $0:获取当前执行的Shell脚本的文件名,如脚本中包含路径,则输出也包括路径
- $n:获取当前执行的Shell脚本的第n个参数值,如n>9,则需要使用用大括号,如${10},各参数间用空格进行分隔
- $#:获取当前执行的Shell脚本传入参数的总个数
- $*:获取当前执行的Shell所有传入参数,如不加引号则与$@功能相同,如果添加双引号"$*",则表示将所有传入参数视为单个字符串,相当于"$1 $2 $3"
- $@:获取当前执行的Shell所有传入参数,如不加引号则与$*功能相同,如果添加双引号"$@",则表示将所有传入参数视为独立的字符串,相当于"$1" "$2" "$3"
当"$*"和"$@"都添加双引号时,两者的功能有所区别;如不加,则功能相同,无区别。
位置参数变量示例
1、示例一:
[root@localhost Test]# cat para.sh
#!/bin/bash
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13} ${14} ${15}
echo '$0 is:' $0
echo '$1 is:' $1
echo '$12 is:' ${12}
echo '$# is:' $#
echo '$* is:' $*
echo '"$*"is:' "$*"
echo '$@ is:' $@
echo '"$@"is:' "$@"
# 输出结果
[root@localhost Test]# bash ~/Test/para.sh {a..z}
a b c d e f g h i j k l m n o
$0 is: /root/Test/para.sh
$1 is: a
$12 is: l
$# is: 26
$* is: a b c d e f g h i j k l m n o p q r s t u v w x y z
"$*"is: a b c d e f g h i j k l m n o p q r s t u v w x y z
$@ is: a b c d e f g h i j k l m n o p q r s t u v w x y z
"$@"is: a b c d e f g h i j k l m n o p q r s t u v w x y z
1、传入的参数个数多于脚本定义的参数时,则多出的参数会忽略
2、传入的参数中如使用双引号,则会当作一个参数值进行传递
3、位置参数如大于9,需要使用${}进行传递
2、示例二:
[root@localhost Test]# cat testposition.sh
#!/bin/bash
echo '$# $1 $2 $3 $* $@'
echo $# $1 $2 $3 $* $@
echo "************"
echo '$*'
for tmp in $*
do
echo $tmp
done
echo "************"
echo "@@@@@@@@@@@@"
echo '$@'
for temp in $@
do
echo $temp
done
echo "@@@@@@@@@@@@"
echo '"*"*"*"*"*"*'
echo '$*'
for i in "$*"
do
echo $i
done
echo '"*"*"*"*"*"*'
echo '"@"@"@"@"@"@'
echo '$@'
for j in "$@"
do
echo $j
done
echo '"@"@"@"@"@"@'
[root@localhost Test]# bash testposition.sh "Hello Jack" Welcome "to Shanghai"
$# $1 $2 $3 $* $@
3 Hello Jack Welcome to Shanghai Hello Jack Welcome to Shanghai Hello Jack Welcome to Shanghai
************
$* # 未加双引号,所以会输出全部参数,则第一个和第三个参数会拆开
Hello
Jack
Welcome
to
Shanghai
************
@@@@@@@@@@@@
$@ # 未加双引号,所以会输出全部参数,则第一个和第三个参数会拆开
Hello
Jack
Welcome
to
Shanghai
@@@@@@@@@@@@
"*"*"*"*"*"*
$* # 添加双引号后,传入的参数全部当一个参数进行输出
Hello Jack Welcome to Shanghai
"*"*"*"*"*"*
"@"@"@"@"@"@
$@ # 添加双引号后,传入的参数全部当独立的参数进行输出
Hello Jack
Welcome
to Shanghai
"@"@"@"@"@"@
状态变量
- $?:获取上一个命令或脚本的执行状态值(0:成功,其他:失败)
- $$:获取当前执行的Shell的进程号(PID)
- $!:获取上一个在后台工作的进程的进程号
- $_:获取在些之前执行的命令或脚本的最后一个参数
以上四个状态变量,仅$?常用,其他三个了解即可。
在日常使场景中,$?主要用法如下所示:
- 1、判断命令和脚本是否执行成功
- 2、如脚本中调用exit 数字,则会返回该数字给$?
- 3、如在函数中,则可以通过return 数字将该数字返回给$?
状态变量示例
1、$?示例:
[root@localhost Test]# ll /etc/profile
-rw-r--r--. 1 root root 1819 4月 11 2018 /etc/profile
[root@localhost Test]# echo $?
0
[root@localhost Test]# ll /etc/profild
ls: 无法访问/etc/profild: 没有那个文件或目录
[root@localhost Test]# echo $?
2
2、$$示例:
[root@localhost Test]# cat testPID.sh
#!/bin/bash
echo $$ > /tmp/test.pid
sleep 300
[root@localhost Test]# bash testPID.sh & # 将当前脚本调用到后台执行
[1] 1671
[root@localhost Test]# ps -ef | grep testPID | grep -v grep
root 1671 23706 0 16:37 pts/0 00:00:00 bash testPID.sh # 查询PID
3、$!示例:
$!功能类似于$$,只不过是获取上一次执行脚本的PID
[root@localhost Test]# bash testPID.sh &
[1] 24078
[root@localhost Test]# echo $!
24078 # 打印上一次在后台执行的进程号
[root@localhost Test]# ps -ef | grep testPID | grep -v grep
root 24078 23706 0 16:42 pts/0 00:00:00 bash testPID.sh
4、$_示例:
[root@localhost Test]# bash para.sh {a..z}
a b c d e f g h i j k l m n o
$0 is: para.sh
$1 is: a
$12 is: l
$# is: 26
$* is: a b c d e f g h i j k l m n o p q r s t u v w x y z
"$*"is: a b c d e f g h i j k l m n o p q r s t u v w x y z
$@ is: a b c d e f g h i j k l m n o p q r s t u v w x y z
"$@"is: a b c d e f g h i j k l m n o p q r s t u v w x y z
[root@localhost Test]# echo $_
z # 打印最后一个传入的参数值
Bash 内置变量
常用的内部命令有echo、eval、exec、export、read、shift、exit。
echo
主要用于打印信息,其命令格式如下所示:
echo [options] args
常用参数如下所示:
参数选项 | 说明 |
---|---|
-n | 不换行输出内容 |
-e | 解析转义字符 |
echo常用转义字符如下:
转义字符 | 说明 |
---|---|
\n | 换行 |
\r | 回车 |
\t | Tab |
\b | 退格 |
\v | 纵向制表符 |
eval
当Shell程序运行到eval语句时,将读入参数args,并将它们组合成一个新的命令而后执行。其命令格式如下所示:
eval args
exec
exec主要用于在不创建新的子进程的情况下,转而执行指定的命令,当指定命令执行完后,则终止该进程。其命令格式如下所示:
exec args
当使用exec打开文件后,read命令每次都会将文件指针移动到下一行进行读取,直至结束。因此常用来处理文件内容。
read
从标准输入读取变量或字符串等信息并传递给其他变量,其命令格式如下所示
read args
shift
对传入的位置参数依次向左移动一个位置,并使用位置参数$#减1,直至0为止。其命令格式如下所示:
shift postition args
shift如果不带参数,则默认左移1位
如传入的参数为$1 $2 $3,如执行一次shift,则之前的$3变成$2,$2变成$1,$1消失。
exit
常用于退出Shell,在日常使用过程中可使用exit num来自定义返回状态数。
Bash 内置变量示例
1、echo
[root@localhost Test]# echo "Test";echo "Dao"
Test
Dao
[root@localhost Test]# echo -n "Test";echo "Dao"
TestDao
[root@localhost Test]# echo -e "Test\tName\n Dao"
Test Name
Dao
2、eval
[root@localhost Test]# cat eval.sh
#!/bin/bash
echo "No eval"
echo \$$#
echo "Add eval"
eval echo \$$#
[root@localhost Test]# bash eval.sh a b
No eval
$2 # 未添加evel时,$#为2,则输出$2
Add eval
b # 添加evel后,则重新对传入的参数进行解析,则输出传入的第2个参数
3、exec
[root@localhost Test]# exec ls
eval.sh para.sh ping.sh testPID.sh testposition.sh
[admin@localhost ~]$ # 在执行exec后则终止当前Shell进程,因此从root用户退出到普通用户
# 与read一起读取文件
[root@localhost ~]# seq 5 > /tmp/rand.log
[root@localhost ~]# cat /tmp/rand.log
1
2
3
4
5
[root@localhost Test]# cat exec.sh
#!/bin/bash
exec < /tmp/rand.log
while read line
do
echo $line
done
echo "Completed"
[root@localhost Test]# bash exec.sh
1
2
3
4
5
Completed
4、read
可以参考公众号中read命令一文
5、shift
[root@localhost Test]# cat shift.sh
#!/bin/bash
echo $1 $2 $3 $4 $5
until [ -z $1 ]
do
echo $@
shift 1
done
[root@localhost Test]# bash shift.sh {1..5}
1 2 3 4 5
1 2 3 4 5
2 3 4 5
3 4 5
4 5
5
变量扩展
变量扩展说明
Shell中变量扩展说明如下所示:
- ${var}:返回${var}的内容
- ${#var}:返回${var}的字符长度
- ${var:offset}:返回${var}从位置offset之后开始提取字符至结束
- ${var:offset:length}:返回${var}从offset之后,提取长度为length的字符
- ${var#word}:返回从${var}开头开始删除最短匹配的word子符串
- ${var##word}:返回从${var}开头开始删除最长匹配的word子符串
- ${var%word}:返回从${var}结尾开始删除最短匹配的word子符串
- ${var%%word}:返回从${var}结尾开始删除最长匹配的word子符串
- ${var/oldstring/newstring}:使用newstring替换第一个匹配的字符oldstring
- ${var//oldstring/newstring}:使用newstring替换所有匹配的字符oldstring
- ${var:-word}:如果变量var的值为空或未赋值,则将word做为返回值,常用于防止变量为空或未定义而导致的异常
- ${var:=word}:如果变量var的值为空或未赋值,则将word赋值给var并返回其值。
- ${var:?word}:如果变量var的值为空或未赋值,则将word做为标准错误输出,否则则输出变量的值,常用于捕捉因变量未定义而导致的错误并退出程序
- ${var:+word}:如果变量var的值为空或未赋值,则什么都不做,否则word字符将替换变量的值
其中${var:-word}、${var:=word}、${var:?word}、${var:+word}中的冒号也可以省略,则将变量为空或未赋值修改为未赋值,去掉了为空的检测, 即运算符仅检测变量是否未赋值
变量扩展示例
[root@localhost init.d]# var="This is test string"
[root@localhost init.d]# echo $var
This is test string
[root@localhost init.d]# echo ${var}
This is test string
[root@localhost init.d]# echo ${#var} # 统计字符长度
19
[root@localhost init.d]# echo ${var:5} # 从第5个位置开始截取字符
is test string
[root@localhost init.d]# echo ${var:5:2} # 从第5个位置开始截取2个字符
is
[root@localhost init.d]# echo ${var#This} # 从开头删除最短匹配的字符 is
is test string
[root@localhost init.d]# echo ${var##This} # 从开头删除最长匹配的字符 is
is test string
[root@localhost init.d]# echo ${var%g} # 从结尾删除最短匹配的字符 is
This is test strin
[root@localhost init.d]# echo ${var%%g} # 从结尾删除最长匹配的字符 is
This is test strin
[root@localhost init.d]# echo ${var/is/newis} # 替换第一个匹配的字符
Thnewis is test string
[root@localhost init.d]# echo ${var//is/newis} # 替换所有匹配到的字符
Thnewis newis test string
[root@localhost init.d]# echo $centos # 变量未定义
[root@localhost init.d]# echo ${centos:-UNDEFINE} # 变量为空,返回UNDEFINE
UNDEFINE
[root@localhost init.d]# centos="CentOS"
[root@localhost init.d]# echo ${centos:-UNDEFINE} # 变量已经定义,返回变量本身的值
CentOS
[root@localhost init.d]# unset centos # 取消变量值
[root@localhost init.d]# echo $centos
[root@localhost init.d]# result=${centos:=UNDEFINE}
[root@localhost init.d]# echo $result
UNDEFINE
[root@localhost init.d]# echo $centos # 变量值为空,则将UNDEFINE赋值给centos
UNDEFINE
[root@localhost init.d]# unset centos
[root@localhost init.d]# echo ${centos:?can not find variable centos}
-bash: centos: can not find variable centos # 变量值为空,输出自定义错误信息
[root@localhost init.d]# centos="IS DEFINED"
[root@localhost init.d]# echo ${centos:?can not find variable centos}
IS DEFINED #变量值已定义,则输出变量值
[root@localhost init.d]# unset centos
[root@localhost init.d]# echo ${centos:+do nothing} # 变量值为空,什么都不操作输出
[root@localhost init.d]# centos="do"
[root@localhost init.d]# echo ${centos:+do nothing} # 变量已赋值,则输出自定义的消息
do nothing
本文同步在微信订阅号上发布,如各位小伙伴们喜欢我的文章,也可以关注我的微信订阅号:woaitest,或扫描下面的二维码添加关注:
Shell编程-03-Shell中的特殊变量和扩展变量的更多相关文章
- shell编程系列6--shell中的函数
shell编程系列6--shell中的函数 .函数介绍 linux shell中的函数和大多数编程语言中的函数一样 将相似的任务或者代码封装到函数中,供其他地方调用 语法格式 第一种格式 name() ...
- centos shell编程5 LANMP一键安装脚本 lamp sed lnmp 变量和字符串比较不能用-eq cat > /usr/local/apache2/htdocs/index.php <<EOF重定向 shell的变量和函数命名不能有横杠 平台可以用arch命令,获取是i686还是x86_64 curl 下载 第三十九节课
centos shell编程5 LANMP一键安装脚本 lamp sed lnmp 变量和字符串比较不能用-eq cat > /usr/local/apache2/htdocs/ind ...
- shell编程系列7--shell中常用的工具find、locate、which、whereis
shell编程系列7--shell中常用的工具find.locate.which.whereis .文件查找之find命令 语法格式:find [路径] [选项] [操作] 选项 -name 根据文件 ...
- 【Shell编程】Shell程序设计
1.Shell简介 作为Linux灵感来源的Unix系统最初是没有图形化界面的,所有的任务都是通过命令行来实现的.因此,Unix的命令行系统得到了很大的发展,逐步成为一个功能强大的系统. Sh ...
- shell编程01—shell基础
01.学习shell编程需要的知识储备 1.vi.vim编辑器的命令,vimrc设置 2.命令基础,100多个命令 3.基础.高端的网络服务,nfs,rsync,inotify,lanmp,sersy ...
- 【Shell编程】Shell基本语法
Shell 语法 Shell程序设计作为一种脚本语言,在Linux系统中有广泛的应用,本文记录了关于Shell程序设计的基础语法知识和常用命令,方便查询,熟练使用shell也需要经常实践,这对于完 ...
- Linux shell编程02 shell程序的执行 及文件权限
第一个shell脚本 1. shell编程的方式 交互式shell编程 非交互式shell编程:执行的语句存放到一个文件 shell脚本:可以任意文件名,建议扩展名为sh 2. ...
- Shell编程(二)——shell的基础知识及常用命令
shell的基础知识 一.bash有以下特点: 1.记录命令历史 2.指令和文件名补全 3.别名 alias rm='rm -i' 4.通配符 * 0个或多个字符 ?匹配一个字符 5 输入输出重定向 ...
- Linux - 简明Shell编程03 - 字符串(String)
脚本地址 https://github.com/anliven/L-Shell/tree/master/Shell-Basics 示例脚本及注释 #!/bin/bash str="Shell ...
随机推荐
- 【linux】centos6.5上bugzilla的搭建
1.安装依赖包 CentOS 6.5默认安装了apche,perl ,需要安装httpd mod_ssl mysql-server mysql php-mysql gcc perl* mod_perl ...
- 查看ms SQL Server存储过程,函数的内容
方法1:最简单的,右键单击要查看的存储过程,选择“修改”: 方法2: SELECT definition FROM solar.sys.sql_modules WHERE [object_id]=(O ...
- thinkpad t420安装debian需要注意的细节
关闭双显卡,使用集成显卡,32位可以用独显跑起来,但是64位的wheezy只能兼容集成显卡,不知道为啥,否则会在某些usb插入/或者拔出来以后,重启提示 failed to execute /lib/ ...
- cocos2d-x 3.0 场景切换特效汇总(转)
cocos2d-x 3.0中场景切换特效比较多,而且游戏开发中也经常需要用到这些特效,来使场景切换时不至于那么干巴,遂这里汇总一下,开发中使用. 场景切换用到导演类Directory,大多数用的都是替 ...
- websocket之四:WebSocket 的鉴权授权方案
引子 WebSocket 是个好东西,为我们提供了便捷且实时的通讯能力.然而,对于 WebSocket 客户端的鉴权,协议的 RFC 是这么说的: This protocol doesn’t pres ...
- [转]oracle 12c 中的分页子句
转自:http://blog.itpub.net/271063/viewspace-1061279/ -- 连接数据库 创建测试用户-- Connected to Oracle Database 12 ...
- CFGym 100198G 题解
一.题目链接 http://codeforces.com/gym/100198/problem/G 二.题意 看样例就能明白,写表达式解析器. 三 .思路 一看这题目,立马就会想到“后缀表达式”,考虑 ...
- CEP实时分析模型
大数据量的实时分析场景: 股票实时分析系统:大数据量(基于内存),要求分析汇总数据
- springboot 邮件服务
springboot仍然在狂速发展,才五个多月没有关注,现在看官网已经到1.5.3.RELEASE版本了.准备慢慢在写写springboot相关的文章,本篇文章使用springboot最新版本1.5. ...
- jenkins显示html样式问题的几种解决方案总结
前言 jenkins上使用HTML Publisher plugin插件生成的html报告样式会丢失,需要设置下才能正常显示. 一.样式丢失 1.官方文档的解释如下,参考地址https://stack ...