您的位置:首页 > 运维架构 > Shell

bash变量简单操作总结及一些特殊变量

2014-07-03 17:42 357 查看
${varname:-word} 如果varname存在且非null,则返回其值;否则,返回word。
${varname:=word} 如果varname存在且非null,则返回其值;否则,设置它为word,并返回其值。
${varname:?message} 如果varname存在且非null,则返回其值;否则,显示varname:message,并退出当前的命令或脚本。省略message会出现默认信息parameter null or not set。注意,在交互式Shell下不需要退出(在不同的Shell间会有不同的行为,用户需自行注意)。
${varname:+word} 如果varname存在且非null,则返回word;否则,返回null。

每个运算符内的冒号(:)都是可选的。如果省略冒号,则将每一个定义中的“存在且非null“部分改为”存在“,也就是说,运算符仅用于测试变量是否存在。

${varname#key_word} 如变量内容从头开始的数据符合key_word,则将符合的最短数据删除。
${varname##key_word} 如变量内容从头开始的数据符合key_word,则将符合的最长数据删除。
${varname%key_word} 如变量内容从尾向前的数据符合key_word,则将符合的最短数据删除。
${varname%%key_word} 如变量内容从尾向前的数据符合key_word,则将符合的最长数据删除。
${varname/old_string/new_string} 如变量内容符合old_string则将第一个old_string会被new_string取代。
${varname/#old_string/new_string} 如变量从头开始符合old_string,则将符合的字符串取代,后面的不取代。
${varname/%old_string/new_string} 如变量从尾开始符合old_string,则将符合的字符串取代,前面的不取代。

${varname//old_string/new_string} 如变量内容符合old_string则将全部的old_string会被new_string取代。
命令行参数替换。 如果脚本需要一个命令行参数,而调用的时候,没用这个参数,这就有可能造成分配一个空变量,这样估计就会引起问题. 可以用下面的方法避免这种问题。

variable=$1_ 赋值的时候增加一个下划线,然后可以用variable=${variable/_/}删除多的一个下划线。
${1:-$DefaultVal} 这里用第一个命令行参数为例$1,如果$1存在且不为空,就返回$1,否则返回默认值。

Shell脚本特殊变量($#,$*和$@)

$# 脚本运行时命令行参数的个数。${$#}就代表了最后一个命令行参数变量,是不正确的。因为不能在花括号里面使用美元符,必须将美元符换成感叹号。${!#}表示最后一个命令行参数变量。

$*和$@能够对命令行参数的快速访问。$*将把命令行的所有参数当成一个参数,而不是多个对象。$@将把命令行的参数都当成独立的单词。

[@localhost scripts]$ cat test.sh
#!/bin/bash

echo "show the result of $* for command line parameters"
for i in "$*"
do
echo $i
done

echo "show the result of $@ for command line parameters"
for i in "$@"
do
echo $i
done
[@localhost scripts]$ bash test.sh para1 para2
show the result of para1 para2 for command line parameters
para1 para2
show the result of para1 para2 for command line parameters
para1
para2


IFS: 查看IFS变量的方法。

$echo $IFS | od -b
通过二进制查看

$set | grep IFS 直接查看IFS变量的值。

$-:记录当前设置的shell选项,默认值是himBH,相关选项介绍可以查看man builtin页面,搜索set命令。

[root@rhel6164 ~]# echo $-
himBH


h:在查找并执行命令时,记住它们的位置

i:interactive 交互式
m:监视模式,作业控制被启用,在支持这个选项的系统中,在交互式shell中是默认启用的。后台进程在单独的进程组中运行,结束时将打印出包含它们退出状态的一行信息
B:Brace expansion 执行花括号扩展
H:允许Enable!样式的历史替换

用到此变量的脚本例子

[root@rhel6164 ~]$ sed -n '67,75p' /etc/profile
for i in /etc/profile.d/*.sh ; do
if [ -r "$i" ]; then
if [ "${-#*i}" != "$-" ]; then #删除变量$-从头开始符合*i的最短数据
. "$i"
else
. "$i" >/dev/null 2>&1
fi
fi
done


${#variable}:返回变量variable值的字符长度

[root@rhel6164 ~]# test="abcdef"
[root@rhel6164 ~]# echo "${#test}" #返回test变量字符长度
6


$[简单的运算]:返回中括号里面运算的结果

判断变量是否被设置

[root@rhel6164 ~]# echo $test

[root@rhel6164 ~]# : ${test?}
-bash: test: parameter null or not set
[root@rhel6164 ~]# test=abcd
[root@rhel6164 ~]# : ${test?}
[root@rhel6164 ~]# ${test?} #不加冒号,就会提示出错,把test当作命令来看待
-bash: abcd: command not found


清空文件内容

[root@rhel6164 test]# cat test.txt
this is testing for eval.
[root@rhel6164 test]# : > test.txt #清空文件test.txt 与 cat /dev/null > test.txt一样,但是:命令为bash的内建命令,执行时将不会产生新的进程
[root@rhel6164 test]# cat test.txt
[root@rhel6164 test]#


-:用于重定向stdin或stdout

[root@rhel6164 test]# tree -A ./*
./test1
mqq test.txt
./test2

0 directories, 1 file
[root@rhel6164 test]# (cd ./test1 && tar cf - . ) | (cd ./test2 && tar xpvf -) #进入test1,然后压缩当前目录里面的内容,然后进入test2目录,进行解压,-分别用于重定向的stdin和stdout
./
./test.txt
[root@rhel6164 test]# ls test2/
test.txt
[root@rhel6164 test]# cp -a ./test1/* ./test1/.[^.]* ./test2 #也可以用这条命令完成上面的操作


$!:在后台运行的最后一个工作的PID(进程ID)

$echo $! #显示最后一个后台运行的进程PID


$_:保存之前执行的命令的最后一个参数

提取子串:

${string:position} 在string中从位置$position开始提取子串,如果要从反方向提取,就在position前面加上一个负号(-)
${string:poistion:length}在string中从位置$position开始提取$length长度的子串

[root@rhel6164 ~]# stringZ=abcABC123abcABC
[root@rhel6164 ~]# echo ${stringZ:2} #从第二个字符位置开始提取
cABC123abcABC
[root@rhel6164 ~]# echo ${stringZ:2:5} #从第二个位置开始提取5个字符
cABC1
[root@rhel6164 ~]# echo ${stringZ:-2} #从字符串尾倒数第二个字符开始提取,默认采用${variable:-word}格式输出,要用括号或者空格来转义这个位置参数
abcABC123abcABC
[root@rhel6164 ~]# echo ${stringZ:(-2)}
BC
[root@rhel6164 ~]# echo ${stringZ: -2}
BC
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: