Shell编程-03-Shell中的特殊变量和扩展变量

特殊变量

? ? 在Shell中的特殊变量主要分别两种位置参数变量状态变量两种。

位置参数变量

? ? Shell中的位置参数变量主要是指$0、$1、$#等,主要用于从命令行、函数或脚本执行等地方传递参数。详细说明如下所示:

  • $0:获取当前执行的Shell脚本的文件名,如脚本中包含路径,则输出也包括路径
  • $n:获取当前执行的Shell脚本的第n个参数值,如n>9,则需要使用用大括号,如${10},各参数间用空格进行分隔
  • $#:获取当前执行的Shell脚本传入参数的总个数
  • $*:获取当前执行的Shell所有传入参数,如不加引号则与[email protected]功能相同,如果添加双引号**"$*",则表示将所有传入参数视为单个字符串**,相当于"$1 $2 $3"
  • [email protected]:获取当前执行的Shell所有传入参数,**如不加引号则与$*功能相同,如果添加双引号"[email protected]",则表示将所有传入参数视为独立的字符串**,相当于"$1" "$2" "$3"

当"$*"和"[email protected]"都添加双引号时,两者的功能有所区别;如不加,则功能相同,无区别。

位置参数变量示例

1、示例一:

[[email protected] 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 ‘[email protected]  is:‘ [email protected]
echo ‘"[email protected]"is:‘ "[email protected]"
# 输出结果
[[email protected] 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
[email protected]  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
"[email protected]"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、示例二:

[[email protected] Test]# cat testposition.sh
#!/bin/bash
echo ‘$# $1 $2 $3 $* [email protected]‘
echo $# $1 $2 $3 $*  [email protected]
echo "************"
echo ‘$*‘
for tmp in $*
 do
   echo $tmp
 done
echo "************"
echo "@@@@@@@@@@@@"
echo ‘[email protected]‘
for temp in [email protected]
 do
  echo $temp
 done
echo "@@@@@@@@@@@@"

echo ‘"*"*"*"*"*"*‘

echo ‘$*‘
for i in "$*"
 do
   echo $i
 done
echo ‘"*"*"*"*"*"*‘

echo ‘"@"@"@"@"@"@‘

echo ‘[email protected]‘
for j in "[email protected]"
 do
  echo $j
 done
echo ‘"@"@"@"@"@"@‘

[[email protected] Test]# bash testposition.sh  "Hello Jack" Welcome "to Shanghai"
$# $1 $2 $3 $* [email protected]
3 Hello Jack Welcome to Shanghai Hello Jack Welcome to Shanghai Hello Jack Welcome to Shanghai
************
$* # 未加双引号,所以会输出全部参数,则第一个和第三个参数会拆开
Hello
Jack
Welcome
to
Shanghai
************
@@@@@@@@@@@@
[email protected] # 未加双引号,所以会输出全部参数,则第一个和第三个参数会拆开
Hello
Jack
Welcome
to
Shanghai
@@@@@@@@@@@@
"*"*"*"*"*"*
$* # 添加双引号后,传入的参数全部当一个参数进行输出
Hello Jack Welcome to Shanghai
"*"*"*"*"*"*
"@"@"@"@"@"@
[email protected] # 添加双引号后,传入的参数全部当独立的参数进行输出
Hello Jack
Welcome
to Shanghai
"@"@"@"@"@"@

状态变量

  • $?:获取上一个命令或脚本的执行状态值(0:成功,其他:失败)
  • $$:获取当前执行的Shell的进程号(PID)
  • $!:获取上一个在后台工作的进程的进程号
  • **$_**:获取在些之前执行的命令或脚本的最后一个参数

以上四个状态变量,仅$?常用,其他三个了解即可。

在日常使场景中,$?主要用法如下所示:

  • 1、判断命令和脚本是否执行成功
  • 2、如脚本中调用exit 数字,则会返回该数字给$?
  • 3、如在函数中,则可以通过return 数字将该数字返回给$?

状态变量示例

1、$?示例:

[[email protected] Test]# ll /etc/profile
-rw-r--r--. 1 root root 1819 4月  11 2018 /etc/profile
[[email protected] Test]# echo $?
0
[[email protected] Test]# ll /etc/profild
ls: 无法访问/etc/profild: 没有那个文件或目录
[[email protected] Test]# echo $?
2

2、$$示例:

[[email protected] Test]# cat testPID.sh
#!/bin/bash
echo $$ > /tmp/test.pid
sleep 300

[[email protected] Test]# bash testPID.sh  & # 将当前脚本调用到后台执行
[1] 1671
[[email protected] 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

[[email protected] Test]# bash testPID.sh  &
[1] 24078
[[email protected] Test]# echo $!
24078 # 打印上一次在后台执行的进程号
[[email protected] Test]# ps -ef | grep testPID | grep -v grep
root     24078 23706  0 16:42 pts/0    00:00:00 bash testPID.sh

4、$_示例:

[[email protected] 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
[email protected]  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
"[email protected]"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
[[email protected] 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

[[email protected] Test]# echo "Test";echo "Dao"
Test
Dao
[[email protected] Test]# echo -n "Test";echo "Dao"
TestDao
[[email protected] Test]# echo -e "Test\tName\n Dao"
Test    Name
 Dao

2、eval

[[email protected] Test]# cat eval.sh
#!/bin/bash

echo "No eval"
echo \$$#
echo "Add eval"
eval echo \$$#

[[email protected] Test]# bash eval.sh  a b
No eval
$2 # 未添加evel时,$#为2,则输出$2
Add eval
b  # 添加evel后,则重新对传入的参数进行解析,则输出传入的第2个参数

3、exec

[[email protected] Test]# exec ls
eval.sh  para.sh  ping.sh  testPID.sh  testposition.sh
[[email protected] ~]$  # 在执行exec后则终止当前Shell进程,因此从root用户退出到普通用户
# 与read一起读取文件
[[email protected] ~]# seq 5 > /tmp/rand.log
[[email protected] ~]# cat /tmp/rand.log
1
2
3
4
5
[[email protected] Test]# cat exec.sh
#!/bin/bash
exec < /tmp/rand.log
while read line
 do
  echo $line
 done
echo "Completed"

[[email protected] Test]# bash exec.sh
1
2
3
4
5
Completed

4、read

可以参考公众号中read命令一文

5、shift

[[email protected] Test]# cat shift.sh
#!/bin/bash
echo $1 $2 $3 $4 $5
until [ -z $1 ]
do
  echo [email protected]
  shift 1
done
[[email protected] 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}中的冒号也可以省略,则将变量为空或未赋值修改为未赋值,去掉了为空的检测, 即运算符仅检测变量是否未赋值

变量扩展示例

[[email protected] init.d]# var="This is test string"
[[email protected] init.d]# echo $var
This is test string
[[email protected] init.d]# echo ${var}
This is test string
[[email protected] init.d]# echo ${#var} # 统计字符长度
19
[[email protected] init.d]# echo ${var:5} # 从第5个位置开始截取字符
is test string
[[email protected] init.d]# echo ${var:5:2} # 从第5个位置开始截取2个字符
is
[[email protected] init.d]# echo ${var#This} # 从开头删除最短匹配的字符 is
is test string
[[email protected] init.d]# echo ${var##This}  # 从开头删除最长匹配的字符 is
is test string
[[email protected] init.d]# echo ${var%g} # 从结尾删除最短匹配的字符 is
This is test strin
[[email protected] init.d]# echo ${var%%g} # 从结尾删除最长匹配的字符 is
This is test strin
[[email protected] init.d]# echo ${var/is/newis} # 替换第一个匹配的字符
Thnewis is test string
[[email protected] init.d]# echo ${var//is/newis} # 替换所有匹配到的字符
Thnewis newis test string

[[email protected] init.d]# echo $centos # 变量未定义

[[email protected] init.d]# echo ${centos:-UNDEFINE} # 变量为空,返回UNDEFINE
UNDEFINE
[[email protected] init.d]# centos="CentOS"
[[email protected] init.d]# echo ${centos:-UNDEFINE} # 变量已经定义,返回变量本身的值
CentOS
[[email protected] init.d]# unset centos # 取消变量值
[[email protected] init.d]# echo $centos

[[email protected] init.d]# result=${centos:=UNDEFINE}
[[email protected] init.d]# echo $result
UNDEFINE
[[email protected] init.d]# echo $centos # 变量值为空,则将UNDEFINE赋值给centos
UNDEFINE
[[email protected] init.d]# unset centos
[[email protected] init.d]# echo ${centos:?can not find variable centos}

-bash: centos: can not find variable centos  # 变量值为空,输出自定义错误信息

[[email protected] init.d]# centos="IS DEFINED"
[[email protected] init.d]# echo ${centos:?can not find variable centos}
IS DEFINED               #变量值已定义,则输出变量值
[[email protected] init.d]# unset centos
[[email protected] init.d]# echo ${centos:+do nothing} # 变量值为空,什么都不操作输出

[[email protected] init.d]# centos="do"
[[email protected] init.d]# echo ${centos:+do nothing}  # 变量已赋值,则输出自定义的消息
do nothing

本文同步在微信订阅号上发布,如各位小伙伴们喜欢我的文章,也可以关注我的微信订阅号:woaitest,或扫描下面的二维码添加关注:

原文地址:https://www.cnblogs.com/surpassme/p/9932841.html

时间: 11-08

Shell编程-03-Shell中的特殊变量和扩展变量的相关文章

shell编程01—shell基础

01.学习shell编程需要的知识储备 1.vi.vim编辑器的命令,vimrc设置 2.命令基础,100多个命令 3.基础.高端的网络服务,nfs,rsync,inotify,lanmp,sersync,sshkey批量分发管理 02.shell脚本概念 1.什么是shell shell是一个命令解释器,在操作系统的最外层,负责直接与用户对话,将用户的输入解释给操作系统,并输出操作系统各种各样的处理结果,输出到屏幕返回给用户.这种对话方式可与是交互式的(键盘输入命令,可以立即得到shell的回

Linux Shell编程实战---Shell中的文本切片技术

Shell中的文本切片技术 在shell中竟然也是有字符串切片这个东西存在的,一直在python中运用切片,下面记录一下shell中切片的用法. (1).替换变量内容中的部分文本 $var="This is a line of text" $ echo${var/line/REPLACED} This is aREPLACED of text" line被替换成REPLACED. (2).指定字符串的起始位置和长度来生成子串 语法如下: ${variable_name:sta

Shell编程中括号判断中赋值语句和判断语句

#!/bin/bash declare var="xxx" # without space and use one = #1.judge whether the assignment statement returns true echo "----------------------test assignment in bracket --------------------------------" [ var="yyyy" ] &&

【转】shell 教程——03 Shell脚本语言与编译型语言的差异

大体上,可以将程序设计语言可以分为两类:编译型语言和解释型语言. 编译型语言 很多传统的程序设计语言,例如Fortran.Ada.Pascal.C.C++和Java,都是编译型语言.这类语言需要预先将我们写好的源代码(source code)转换成目标代码(object code),这个过程被称作“编译”. 运行程序时,直接读取目标代码(object code).由于编译后的目标代码(object code)非常接近计算机底层,因此执行效率很高,这是编译型语言的优点. 但是,由于编译型语言多半运

Linux Shell编程实战---shell实现图片下载神器

$ cat dowonload_image.sh  #!/bin/bash ######################################### #图片下载器                              # #script_name: dowonload_image.sh         # #author:weixiaoxin write by 2017-09-20   #      #########################################

shell编程基础-shell分库备份

分库备份企业实战题7:如何实现对MySQL数据库进行分库备份,请用脚本实现 #!/bin/bash MysqlUser=root PassWord=root Port=3306 Socket="/usr/include/mysql/mysql.sock" MysqlCmd="mysql -u$MysqlUser -p$PassWord -S $Socket" Database=`$MysqlCmd -e "show databases;"|egr

linux学习笔记四(shell编程)

前言:最近在学习shell编程,shell编程是一个很强大的编程语言. 目的:方便今后复习. 内容:1.简单的回顾一下编程语言                 1)编程语言:机器语言,汇编语言,高级语言.                 2)编程语言有静态和动态的区分.                             区别:静态语言是一种编译性的语言,要提前知道变量的格式,进过完整的编译之后才能运行,典型的静态语言包括:C.C++.JAVA.C#.                    

Linux Shell编程基础

在学习Linux BASH Shell编程的过程中,发现由于不经常用,所以很多东西很容易忘记,所以写篇文章来记录一下 ls   显示当前路径下的文件,常用的有 -l 显示长格式  -a 显示所有包括隐藏  -R 显示文件夹内的内容  -c 按照最后一次修改时间排序  -t 按照修改时间排序输出 echo 显示  -n 不换行 touch  创建一个文件,或者修改文件的访问时间和修改时间 touch -a file 只更改访问时间 -m之更改修改实际那 -t指定特定时间 cp  复制文件 -a 保

shell编程进阶

Shell编程进阶 Shell结构以及执行 [[email protected] ~]# mkdir shell [[email protected] ~]# cd shell/ [[email protected] shell]# vim first.sh #!/bin/bash ##The first test shell script ##written by wangchao ls /tmp/ echo "This is the first script." [[email p

shell编程中的变量

变量就是其值可以变化的量;从实质来说,变量名是指向一片用于存储数据的内存空间;变量有本地变量.环境变量之分;shell变量是一种弱类型的变量,在声明变量时并不需要指定其变量类型,默认均为字符型;也不需要遵循C语言中"先声明再使用"的规定,任何时候想用就用; 本地变量:    是指只在某个shell中生效的变量,对其他shell无效,而且会随着当前shell的结束而消失;    本地变量的作用域被限定在声明它们的shell中;    为了让子shell继承当前shell的变量,可以使用e