内部变量,属于环境变量。环境变量还包括用户自定义的环境变量。
BASH记录了bash Shell的路径,通常为/bin/bash,内部变量SHELL就是通过BASH的值确定当前Shell的类型
SHELL 就是通过BASH的值来确定SHELL的类型的。
BASH_SUBSHELL记录了子Shell的层次,这个变量在bash版本3之后才出现的,将在12章介绍
BASH_VERSINFO是一个数组,包含6个元素,这6个元素用于表示bash的版本信息
#!/bin/bash
for n in 0 1 2 3 4 5
do
echo "BASH_VERSINFO[$n]=${BASH_VERSINFO[$n]}"
done
[root@ktz CH09]# ./bashver.sh
BASH_VERSINFO[0]=4 #主版本号
BASH_VERSINFO[1]=1 #次版本号
BASH_VERSINFO[2]=2 #补丁级别
BASH_VERSINFO[3]=1 #编译版本
BASH_VERSINFO[4]=release #发行状态
BASH_VERSINFO[5]=x86_64-redhat-linux-gnu #BASH shell的硬件架构 是基于x64架构
Linux系统的bash Shell版本,包含了主次版本、补丁级别、编译版本和发行状态,即BASH_VERSINFO数组从0到4的值
Linux目录栈用于存放工作目录,便于程序员手动控制目录的切换
bash Shell定义了两个系统命令pushd和popd
pushd命令用于将某目录压入目录栈,同时将当前工作目录切换到入栈的目录
popd命令将栈顶目录弹出,栈顶元素变为下一个元素,同时将当前工作目录切换到栈弹出的目录
DIRSTACK记录了栈顶目录值,初值为空
Last login: Fri Dec 26 23:00:10 2014
[root@ktz ~]#
[root@ktz ~]#
[root@ktz ~]# echo $DIRSTACK
~
[root@ktz ~]# pushd /home
/home ~
[root@ktz home]#
popd 后面不用跟参数,弹出的是栈顶元素
[root@ktz jdk]# pushd jre/
~/jdk/jre ~/jdk ~ ~
[root@ktz jre]#
[root@ktz jre]#
[root@ktz jre]#
[root@ktz jre]# popd
~/jdk ~ ~
GLOBIGNORE是由冒号分隔的模式列表,表示通配(globbing)时忽略的文件名集合
globbing : 通配
nore : 忽略
GLOBIGNORE可以是多个模式,之间以冒号分割
[root@ktz bin]# ll
total 752
-rwxr-xr-x. 1 uucp 143 7949 Sep 27 08:06 appletviewer
-rwxr-xr-x. 1 uucp 143 7925 Sep 27 08:06 apt
lrwxrwxrwx. 1 uucp 143 8 Dec 14 01:06 ControlPanel -> jcontrol
-rwxr-xr-x. 1 uucp 143 7925 Sep 27 08:06 extcheck
-rwxr-xr-x. 1 uucp 143 7957 Sep 27 08:06 idlj
-rwxr-xr-x. 1 uucp 143 7909 Sep 27 08:06 jar
-rwxr-xr-x. 1 uucp 143 7925 Sep 27 08:06 jarsigner
-rwxr-xr-x. 1 uucp 143 7718 Sep 27 08:06 java
-rwxr-xr-x. 1 uucp 143 7925 Sep 27 08:06 javac
-rwxr-xr-x. 1 uucp 143 7925 Sep 27 08:06 javadoc
-rwxr-xr-x. 1 uucp 143 2052 Sep 27 05:06 javafxpackager
-rwxr-xr-x. 1 uucp 143 7925 Sep 27 08:06 javah
-rwxr-xr-x. 1 uucp 143 7925 Sep 27 08:06 javap
-rwxr-xr-x. 1 uucp 143 1809 Sep 27 07:55 java-rmi.cgi
-rwxr-xr-x. 1 uucp 143 132848 Sep 27 08:08 javaws
-rwxr-xr-x. 1 uucp 143 7909 Sep 27 08:06 jcmd
-rwxr-xr-x. 1 uucp 143 7997 Sep 27 08:06 jconsole
-rwxr-xr-x. 1 uucp 143 6391 Sep 27 08:08 jcontrol
-rwxr-xr-x. 1 uucp 143 7965 Sep 27 08:06 jdb
-rwxr-xr-x. 1 uucp 143 7925 Sep 27 08:06 jhat
-rwxr-xr-x. 1 uucp 143 8077 Sep 27 08:06 jinfo
-rwxr-xr-x. 1 uucp 143 8077 Sep 27 08:06 jmap
-rwxr-xr-x. 1 uucp 143 71223 Jul 9 06:21 jmc
-rwxr-xr-x. 1 uucp 143 380 Jul 9 06:29 jmc.ini
-rwxr-xr-x. 1 uucp 143 7909 Sep 27 08:06 jps
-rwxr-xr-x. 1 uucp 143 7933 Sep 27 08:06 jrunscript
-rwxr-xr-x. 1 uucp 143 7965 Sep 27 08:06 jsadebugd
-rwxr-xr-x. 1 uucp 143 8077 Sep 27 08:06 jstack
-rwxr-xr-x. 1 uucp 143 7909 Sep 27 08:06 jstat
-rwxr-xr-x. 1 uucp 143 7925 Sep 27 08:06 jstatd
-rwxr-xr-x. 1 uucp 143 5356 Sep 26 2013 jvisualvm
-rwxr-xr-x. 1 uucp 143 7925 Sep 27 08:06 keytool
-rwxr-xr-x. 1 uucp 143 7933 Sep 27 08:06 native2ascii
-rwxr-xr-x. 1 uucp 143 8117 Sep 27 08:06 orbd
-rwxr-xr-x. 1 uucp 143 7957 Sep 27 08:06 pack200
-rwxr-xr-x. 1 uucp 143 7981 Sep 27 08:06 policytool
-rwxr-xr-x. 1 uucp 143 7909 Sep 27 08:06 rmic
-rwxr-xr-x. 1 uucp 143 7925 Sep 27 08:06 rmid
-rwxr-xr-x. 1 uucp 143 7933 Sep 27 08:06 rmiregistry
-rwxr-xr-x. 1 uucp 143 7941 Sep 27 08:06 schemagen
-rwxr-xr-x. 1 uucp 143 7925 Sep 27 08:06 serialver
-rwxr-xr-x. 1 uucp 143 7949 Sep 27 08:06 servertool
-rwxr-xr-x. 1 uucp 143 8149 Sep 27 08:06 tnameserv
-rwxr-xr-x. 1 uucp 143 219643 Sep 27 08:06 unpack200
-rwxr-xr-x. 1 uucp 143 7925 Sep 27 08:06 wsgen
-rwxr-xr-x. 1 uucp 143 7941 Sep 27 08:06 wsimport
-rwxr-xr-x. 1 uucp 143 7941 Sep 27 08:06 xjc
[root@ktz bin]# GLOBIGNORE="j*"
[root@ktz bin]# echo $GLOBIGNORE
j*
[root@ktz bin]# ll *
-rwxr-xr-x. 1 uucp 143 7949 Sep 27 08:06 appletviewer
-rwxr-xr-x. 1 uucp 143 7925 Sep 27 08:06 apt
lrwxrwxrwx. 1 uucp 143 8 Dec 14 01:06 ControlPanel -> jcontrol
-rwxr-xr-x. 1 uucp 143 7925 Sep 27 08:06 extcheck
-rwxr-xr-x. 1 uucp 143 7957 Sep 27 08:06 idlj
-rwxr-xr-x. 1 uucp 143 7925 Sep 27 08:06 keytool
-rwxr-xr-x. 1 uucp 143 7933 Sep 27 08:06 native2ascii
-rwxr-xr-x. 1 uucp 143 8117 Sep 27 08:06 orbd
-rwxr-xr-x. 1 uucp 143 7957 Sep 27 08:06 pack200
-rwxr-xr-x. 1 uucp 143 7981 Sep 27 08:06 policytool
-rwxr-xr-x. 1 uucp 143 7909 Sep 27 08:06 rmic
-rwxr-xr-x. 1 uucp 143 7925 Sep 27 08:06 rmid
-rwxr-xr-x. 1 uucp 143 7933 Sep 27 08:06 rmiregistry
-rwxr-xr-x. 1 uucp 143 7941 Sep 27 08:06 schemagen
-rwxr-xr-x. 1 uucp 143 7925 Sep 27 08:06 serialver
-rwxr-xr-x. 1 uucp 143 7949 Sep 27 08:06 servertool
-rwxr-xr-x. 1 uucp 143 8149 Sep 27 08:06 tnameserv
-rwxr-xr-x. 1 uucp 143 219643 Sep 27 08:06 unpack200
-rwxr-xr-x. 1 uucp 143 7925 Sep 27 08:06 wsgen
-rwxr-xr-x. 1 uucp 143 7941 Sep 27 08:06 wsimport
-rwxr-xr-x. 1 uucp 143 7941 Sep 27 08:06 xjc
GROUPS记录了当前用户所属的群组,Linux的一个用户可同时包含在多个组内,因此,GROUPS是一个数组,数组记录了当前用户所属的所有群组号
记录了Linux主机的名字
HOSTTYPE和MACHTYPE
记录系统的硬件架构
记录了操作系统类型,Linux系统中,$OSTYPE=linux
REPLY变量与read和select命令有关
read命令用于读取标准输入(stdin)的变量值
read variable #varibale是变量名
read将读到的标准输入存储到variable变量中。read命令也可以不带任何变量名,此时,read就将读到的标准输入存储到REPLY变量中
REPLY 和read
[root@ktz bin]# read
ddddddddd
[root@ktz bin]# echo $REPLY
ddddddddd
[root@ktz bin]# read d
eeeeeeeeeeeeeeeeeee
[root@ktz bin]# echo $d
eeeeeeeeeeeeeeeeeee
REPLY变量与read和select命令有关
bash Shell的select命令源自于Korn Shell,是一种建立菜单的工具,它提供一组字符串供用户选择,用户不必完整地输入字符串,而只需输入相应的序号进行选择
select variable in list
do
Shell命令1
Shell命令2
Shell命令3
……
break
done
select自动将list形成有编号的菜单,用户输入序号以后,将该序号所对应list中的字符串赋给variable变量,而序号值则保存到REPLY变量中
[root@ktz bin]# select v in a b c d e
> do
> echo $REPLY
> echo $v
> break
> done;
1) a
2) b
3) c
4) d
5) e
#? 1
1
a
记录脚本从开始执行到结束所耗费的时间,以秒为单位
$SECONDS 可以获取值
记录了bash Shell嵌套的层次,一般来说,我们启动第一个Shell时,$SHLVL=1,如果在这个Shell中执行脚本,脚本中的SHLVL为2,如果脚本再执行子脚本,子脚本中的SHLVL就变为3
设置Shell的过期时间,当TMOUT不为0时,Shell在TMOUT秒后将自动注销。TMOUT放在脚本中,可以规定脚本的执行时间
#!/bin/bash
TMOUT=3
echo "What is your name?"
read fname
if [ -z "$fname" ]; then
fname="(no answer)"
fi
echo "Your name is $fname"
Shell选项(options)用于设定bash Shell所支持的一些特性,一个Shell选项有“开”和“关”两种状态
set命令用于打开或关闭选项
set -o optionname #打开名为optionname选项
set +o optionname #关闭名为optionname选项
SHELLOPTS记录了处于“开”状态的Shell选项(options)列表,它是一个只读变量
演示例9-12
set命令还可以直接利用选项的简写来开启或关闭选项
选项名称 |
简写 |
意义 |
noclobber |
C |
防止重定向时覆盖文件 |
allexport |
a |
export所有已定义的变量 |
norify |
b |
后台作业运行结束时,发送通知 |
errexit |
e |
当脚本发生第一个错误时,退出脚本 |
noglob |
f |
禁止文件名扩展,即禁用通配(globbing) |
interactive |
i |
使脚本以交互模式运行 |
noexec |
n |
读取脚本中的命令,进行语法检查,但不执行这些命令 |
POSIX |
o posix |
修改bash及其调用脚本的行为,使其符合POSIX标准 |
privileged |
p |
以suid身份运行脚本 |
restricted |
r |
以受限模式运行脚本 |
stdin |
s |
从标准输入(stdin)中读取命令 |
nounset |
u |
当使用未定义变量时,输出错误信息,并强制退出 |
verbose |
v |
在执行每个命令之前,将每个命令打印到标准输出(stdout) |
xtrace |
x |
与verbose相似,但是打印完整命令 |
无 |
D |
列出双引号内以$为前缀的字符串,但不执行脚本中的命令 |
无 |
c … |
从…中读取命令 |
无 |
t |
第一条命令执行结束就退出 |
无 |
- |
选项结束标志,后面跟上位置参数(positional parameter) |
选项名称 |
简写 |
意义 |
noclobber |
C |
防止重定向时覆盖文件 |
allexport |
a |
export所有已定义的变量 |
norify |
b |
后台作业运行结束时,发送通知 |
errexit |
e |
当脚本发生第一个错误时,退出脚本 |
noglob |
f |
禁止文件名扩展,即禁用通配(globbing) |
interactive |
i |
使脚本以交互模式运行 |
noexec |
n |
读取脚本中的命令,进行语法检查,但不执行这些命令 |
POSIX |
o posix |
修改bash及其调用脚本的行为,使其符合POSIX标准 |
privileged |
p |
以suid身份运行脚本 |
restricted |
r |
以受限模式运行脚本 |
stdin |
s |
从标准输入(stdin)中读取命令 |
nounset |
u |
当使用未定义变量时,输出错误信息,并强制退出 |
verbose |
v |
在执行每个命令之前,将每个命令打印到标准输出(stdout) |
xtrace |
x |
与verbose相似,但是打印完整命令 |
无 |
D |
列出双引号内以$为前缀的字符串,但不执行脚本中的命令 |
无 |
c … |
从…中读取命令 |
无 |
t |
第一条命令执行结束就退出 |
无 |
- |
选项结束标志,后面跟上位置参数(positional parameter) |
第4章讲述过awk的字符串处理函数,本节介绍expr命令处理字符串
1、${#string}
2、expr length $string
1、2 都可以用来计算字符串长度
[root@se ~]# str="hello shell"
[root@se ~]# echo ${#str}
11
[root@se ~]# expr length "$str"
11
expr index $string $substring
[root@se ~]# expr index "$str" e
2
expr match $string $substring
#在string的开头匹配substring字符串,中间出现的返回0,匹配不到
#{} 这种形式的命令是从0开始配置
#{string:position}
#从名称为$string的字符串的第$position个位置开始抽取子串,到结束
#{string:position:length} #从名称为$string的字符串的第$position个位置开始抽取长度为$length的子串
注意:#{…}格式的命令从0开始对名称为$string的字符串进行标号
[root@se ~]# echo ${str:0}
hello shell
[root@se ~]# echo ${str:4}
o shell
[root@se ~]# echo ${str:4:5}
o she
#{string: -position} #冒号和横杠符号之间有一个空格符
#{string:(position)} #冒号和左括号之间未必要有空格符
[root@se ~]# echo ${str: -5}
shell
[root@se ~]# echo ${str:(-5)}
shell
expr substr
从1开始编号,和${} 从0开始编号相差了1
expr substr $string $position $length #从名称为$string的字符串的第$position个位置开始抽取长度为$length的子串
注意: expr substr命令是从1开始对名称为$string的字符串进行标号的
删除子串
${string#substring} #删除string开头处与substring匹配的最短子串
${string##substring} #删除string开头处与substring匹配的最长子串
${string%substring} #删除string结尾处与substring匹配的最短子串
${string%%substring} #删除string结尾处与substring匹配的最长子串
echo ${str#2*1}
删除2到1
替换子串命令都是${…}格式,可以在任意处、开头处和结尾处替换满足条件的子串
${string/substring/replacement} #仅替换第一次与substring相匹配的子串
${string//substring/replacement} #替换所有与substring相匹配的子串
${string/#substring/replacement} #替换string开头处与substring相匹配的子串
${string/%substring/replacement} #替换string结尾处与substring相匹配的子串
declare 和typeset
declare
Typeset
两个命令用于指定变量的类型,两个命令是完全等价的
declare
declare [选项] 变量名
选项名 |
意义 |
-r |
将变量设置为只读属性 |
-i |
将变量定义为整型数 |
-a |
将变量定义为数组 |
-f |
显示此脚本前定义过的所有函数名及其内容 |
-F |
仅显示此脚本前定义过的所有函数名 |
-x |
将变量声明为环境变量 |
(( ... )) 方法
let 命令 用于执行数值运算
((…))格式,可以用于算术运算
双小括号方法也可以使bash Shell实现C语言风格的变量操作
declare命令的-x选项将变量声明为环境变量,相当于export命令,但是,declare -x允许在声明变量为环境变量的同时给变量赋值,而export命令不支持此功能
declare -x variable-name=value
使用let和使用(())的区别
let var3=1+2
echo “$var3”
declare -i var1
var1=1+2
echo $var1
echo $((1+2))
什么是间接变量引用
variable1=variable2
variable2=value
variable1的值是variable2,而variable2又是变量名,variable2的值为value,间接变量引用是指通过variable1获得变量值value的行为
bash Shell提供的两种实现间接变量引用的格式
eval tempvar=\$$variable1
tempvar=${!variable1}
#!/bin/bash
S01_name="Li Hao"
S01_dept=Computer
S01_phone=025-83481010
S01_rank=5
S02_name="Zhang Ju"
S02_dept=English
S02_phone=025-83466524
S02_rank=8
S03_name="Zhu Lin"
S03_dept=Physics
S03_phone=025-83680010
S03_rank=3
PS3='Pls. select the number of student:'
select stunum in "S01" "S02" "S03"
do
name=${stunum}_name
dept=${stunum}_dept
phone=${stunum}_phone
rank=${stunum}_rank
echo "BASIC INFORMATION OF NO.$stunum STUDENT:"
echo "NAME:${!name}"
echo "DEPARTMENT:${!dept}"
echo "PHONE:${!phone}"
echo "RANK:${!rank}"
break
done
#!/bin/bash
filename=$1
column=$2
tempvar=${!column}
echo $column
echo $2
echo $filename
awk 'BEGIN {FS=","}
{print NR,$tempvar}' $filename