Bash变量



-----------------------------------------------------------------Sun-------------------------------------------------------------------



一、内置变量

1.$BASH

Bash的二进制程序文件的路径(脚本解释器的路径)


#!/bin/bash

echo $BASH
结果: /bin/bash

2.$FUNCNAME

当前函数的名字


#!/bin/bash

xyz23 ()
{
echo "$FUNCNAME now executing"
}

xyz23
echo "FUNCNAME = $FUNCNAME"
结果为:   

<span style="font-size:14px;"></span><pre name="code" class="objc">xyz23 now executing
FUNCNAME now #由于超出了函数的作用域,无法打印函数的名字,所以显示为null

 

3.$IFS

内部域分隔符,这个变量用来决定 Bash 在解释字符串时如何识别域,或者单词边界。

$IFS默认为空白(空格,制表符,和换行符),但这是可以修改的,比如,在分析逗号分隔的数据文件时,就可以设置为逗号

#!/bin/bash

output_args_one_per_line()                  
{
for arg
do echo "[$arg]"
done
}

echo "IFS=\" \"" 

IFS=" "                                                  #定分隔符为 空格
var="a  b   c"                                        #分析此带空格的变量
output_args_one_per_line $var
#结果是:
#IFS=" "
#[a]
#[b]
#[c]


echo "IFS=:"

IFS=:                                                    #定分隔符为 :
var="a::b:::c::::"                                    
output_args_one_per_line $var
# 结果是:                                            #将原先的 : 转换为 空格 
[a]
[]
[b]
[]
[]
[c]
[]
[]
[]

4、$REPLY

当没有参数变量提供给 read 命令的时候,这个变量会作为默认变量提供给 read 命令。也可以用于 select 菜单,但是只提供所选择变量的编号,而不是变量本身的值。


#!/bin/bash

echo -n "What is your favorite fruit?"

<span style="color:#CC66CC;">read</span>

echo "My favorite fruit is <span style="color:#CC66CC;">$REPLY</span>"

#结果为
#What is your favorite fruit?apple
#My favorite fruit is apple



echo -n "What is your favorite animal?"

<span style="color:#CC66CC;">read animal</span>
echo "My favorite animal is <span style="color:#CC66CC;">$animal</span>"
echo "but .."
echo "Value of \$REPLY is still <span style="color:#CC66CC;">$REPLY</span>"    
#       $REPLY 仍保留上一次 read 到的,因为 $animal 被传入到了新的 read 命令中

#结果为:
#What is your favorite animal?rabbit
#My favorite animal is rabbit
#but ..
#Value of $REPLY is still apple

5.通过$*$@列出所有的参数

"$*" 所有的位置参数都被看作为一个单词。

 $@$* 相同,但是每个参数都是一个独立的引用字符串,这就意味着,参数是被完整传递的,并没有被解释或扩展。这也意味着,参数列表中每个参数都被看作为单独的单词。

index=1

echo "Listing args with \"\$*\":"
for arg in "$*"                                                  <code class="hljs bash"> <span class="hljs-comment"># 如果"$*"不被""(双引号)引用,那么将不能正常地工作.</span></code>
do
echo "Arg #$index = $arg"
let "index+=1"
done                                                                #<span style="color:#CC66CC;"><strong> $* 将所有参数看成一个单词</strong></span>
echo "Entire arg list seen as single word"

index=1

echo "Listing args with \"\$@\":"
for arg in "$@"
do
echo "Arg #$index = $arg"
let "index+=1"
done                                                               <code class="hljs bash"><span class="hljs-comment">#<strong><span style="color:#CC66CC;"> $@ 把每个参数都看成是单独的单词.</span></strong></span></code>
echo "Arg list seen as separate words"

index=1

echo "Listing args with \$*"
for arg in $*
do
echo "Arg #$index = #arg"
let "index+=1"
done                                                              #<code class="hljs bash"><span class="hljs-comment"> <strong><span style="color:#CC66CC;">未引用的$*将会把参数看成单独的单词.</span></strong></span></code><strong><span style="color:#CC66CC;"></span></strong>
<pre name="code" class="objc">echo "Arg list seen as separate words"

 结果为: 

Listing args with "$*":
Arg #1 =
Entire arg list seen as single word

Listing args with "$@":
Arg list seen as separate words

Listing args with $*
Arg list seen as separate words



二、操作字符串

1.字符串长度

#!/bin/bash

string=abcABC123ABCabc
<span style="font-size:12px;color:#CC66CC;">echo ${#string}                    # 15
expr length $string              # 15</span>


2.使用awk来处理字符串

Bash脚本也可以调用awk的字符串操作功能来代替它自己内建的字符串操作。


#!/bin/bash

String=23skidoo1
#      012345678    Bash
#      123456789    awk
# 注意不同的字符串索引系统:
<strong><span style="font-size:12px;color:#CC66CC;"># Bash的第一个字符是从'0'开始记录的.
# Awk的第一个字符是从'1'开始记录的.
</span></strong>
echo ${String:2:4}         # 位置 3 (0-1-2), 4 个字符长


# <span style="font-size:12px;color:#CC66CC;"><strong>awk中等价于${string:pos:length}的命令是substr(string,pos,length).</strong></span>
echo | awk '
{
    <span style="font-size:14px;">print substr("'"${String}"'",3,4)      </span>
}
'

#  使用一个空的"echo"通过管道传递给awk一个假的输入,
#+ 这样就不必提供一个文件名给awk.


三、参数替换

1.处理和(或)扩展变量

${parameter} 与 $parameter 相同,也就是变量 parameter 的值。但在某些情况下,最好使用${parameter} 以避免产生混淆。

#!/bin/bash

your_id=${USER}-on-${HOMENAME}

echo "your_id"
echo "Old \$PATH = $PATH"
PATH=${PATH}:/opt/bin                  #/opt/bin 添加到PATH变量中
echo "New \$PATH = $PATH"


${parameter-default} 如果变量 parameter 没被声明,那么就使用默认值。

${parameter:-default} 如果变量 parameter 没被设置,那么就使用默认值。


username=
echo "username has been declared,bu is set to null"
echo "username = ${username-`whoami`}"

echo username1 has not been declared
echo "username 1 = ${username1-`whoami`}"

username2=
echo "username2 has not bee declared"
echo "username2 = ${username2:-`whoami`}"
结果为:
username =
username1 has not been declared
username1 = hahahaha
username2 has not bee declared
username2 = hahahaha




指定方式说明
${parameter-default}如果变量 parameter 没被声明,那么就使用默认值。
${parameter:-default}如果变量 parameter 没被设置,那么就使用默认值。
${parameter=default}如果变量parameter没声明,那么就把它的值设为default。
${parameter:=default}如果变量parameter没设置,那么就把它的值设为default。
${parameter+alt_value}如果变量parameter被声明了,那么就使用alt_value,否则就使用null字符串。
${parameter:+alt_value}如果变量parameter被设置了,那么就使用alt_value,否则就使用null字符串。
${parameter?err_msg}如果parameter已经被声明,那么就使用设置的值,否则打印err_msg错误消息。
${parameter:?err_msg}如果parameter已经被设置,那么就使用设置的值,否则打印err_msg错误消息。


#!/bin/bash

#  检查一些系统环境变量.
#  这是一种可以做一些预防性保护措施的好习惯.
#  比如, 如果$USER(用户在控制台上中的名字)没有被设置的话,
#+ 那么系统就会不认你.

: ${HOSTNAME?} ${USER?} ${HOME?} ${MAIL?}

echo "Name of the machine is $HOSTNAME."
echo "You are $USER."
echo "Your home directory is $HOME."
echo "Your mail INBOX is located in $MAIL."

echo "If you are reading this message,"
echo "critical environmental variables have been set."
echo
echo

# ------------------------------------------------------

#  ${variablename?}结构
#+ 也能够检查脚本中变量的设置情况.

ThisVariable=Value-of-ThisVariable
#  注意, 顺便提一下,这个字符串变量可能会被设置一些非法字符.
: ${ThisVariable?}
echo "Value of ThisVariable is $ThisVariable".
echo



: ${ZZXy23AB?"ZZXy23AB has not been set."}
#  如果变量ZZXy23AB没有被设置的话, 那么这个脚本会打印一个错误信息, 然后结束.

# 可以自己指定错误消息.
# : ${variablename?"ERROR MESSAGE"}

# 等价于:    dummy_variable=${ZZXy23AB?}
#               dummy_variable=${ZZXy23AB?"ZXy23AB has not been set."}
#
#                echo ${ZZXy23AB?} >/dev/null

#  使用命令"set -u"来比较这些检查变量是否被设置的方法.

echo "You will not see this message, because script already terminated."

HERE=0
exit $HERE   # 不会在这里退出.

# 事实上, 这个脚本将会以返回值1作为退出状态(echo $?).

2.变量长度/子串删除

${#var} 字符串长度(变量$var得字符个数)。

对于array来说,${#array}表示的是数组中第一个元素的长度


#!/bin/bash

E_NO_ARGS=65

if [ $# -eq 0 ]  # 这个演示脚本必须有命令行参数.
then
echo "Please invoke this script with one or more command-line arguments."
exit $E_NO_ARGS
fi  

var01=abcdEFGH28ij
echo "var01 = ${var01}"
echo "Length of var01 = ${#var01}"


# 现在, 让我们试试在变量中嵌入一个空格.
var02="abcd EFGH28ij"                                     # 程序会把空格后的当命令
echo "var02 = ${var02}"                                     # 由于出错 var02 为空
echo "Length of var02 = ${#var02}"

echo "Number of command-line arguments passed to script = ${#@}"
echo "Number of command-line arguments passed to script = ${#*}"

exit 0

{var#Pattern}, ${var##Pattern} 从变量$var的开头删除最短或最长匹配$Pattern的子串。

“#”表示匹配最短,“##”表示匹配最长。


3.变量扩展/子串替换

${var:pos} 变量var从位置pos开始扩展, 也就是pos之前的字符都丢弃。

${var:pos:len} 变量var从位置pos开始,并扩展len个字符。

${var/Pattern/Replacement} 使用Replacement来替换变量var中第一个匹配Pattern的字符串。

${var//Pattern/Replacement} 全局替换。所有在变量var匹配Pattern的字符串,都会被替换为Replacement。

#!/bin/bash

var1=abcd-1234-defg
echo "var1 = $var1"

t=${var1#*-*}
echo "var1 = $t"         # var1 = 1234-defg

 t=${var1##*-*}
echo "var1 = $t"         # var1 中包含 - ,所以返回为空

t=${var1%*-*}
echo "var1 = $t"         # var1 = abcd-1234



${var/#Pattern/Replacement} 如果变量var的前缀匹配Pattern,那么就使用Replacement来替换匹配到Pattern的字符串。

${var/%Pattern/Replacement} 如果变量var的后缀匹配Pattern,那么就使用Replacement来替换匹配到Pattern的字符串。


v0=abc1234zip123abc
echo "v = $v"

v1=${v0/#abc/ABCDEF}
echo "v1 = $v1"

v2=${v0/%abc/ABCDEF}
echo "v2 = $v2"

v3=${v0/#123/000}            #只会匹配开头的
echo "v3 = $v3"

v4=${v0/%123/000}           #只会匹配结尾的
echo "v4 = $v4"

结果为:

v1 = ABCDEF1234zip123abc
v2 = abc1234zip123ABCDEF
v3 = abc1234zip123abc
v4 = abc1234zip123abc

四、指定变量的类型: 使用declare或者typeset

1.declare/typeset选项

选项说明
-r只读
-i整型
-a数组
-f函数
-xexport

2.使用declare来指定变量的类型

#!/bin/bash

func1 ()
{
echo haha
}
declare -f                           # 打印已定义的函数

declare -i var1
var1=2345
echo "var1 = $var1"            # var1 = 2345

var1=2367.4                       # 修改 var1 的值
echo "var1 = $var1"            #产生错误信息,var1 仍为2345


declare -r var2=142.23       # 设置var2 为只读属性
echo "var2 = $var2"

var2=67.23                        # 赋值产生错误消息,并从脚本退出

五、变量的间接引用

1.间接引用

假设一个变量的值是第二个变量的名字。如果a=letter_of_alphabet并且letter_of_alphabet=z,它被称为间接引用。

通过引用变量a来获得z,它使用  eval var1=\$$var2   这种不平常的形式。


2.传递一个间接引用给awk

#!/bin/bash

#  这是"求文件中指定列的总和"脚本的另一个版本,
#  这个脚本可以计算目标文件中指定列(此列的内容必须都是数字)的所有数字的和.
#  这个脚本使用了间接引用.

ARGS=2
E_WRONGARGS=65

if [ $# -ne "$ARGS" ] # 检查命令行参数的个数是否合适.
then
echo "Usage: `basename $0` filename column-number"
exit $E_WRONGARGS
fi

filename=$1
column_number=$2

#===== 在这一行上边的部分, 与原始脚本是相同的 =====#

# 多行的awk脚本的调用方法为: awk ' ..... '

# awk脚本开始.
# ------------------------------------------------
awk "

{ total += \$${column_number} # 间接引用
}
END {
  print total
}

" "$filename"
# ------------------------------------------------
# awk脚本结束.

exit 0


六、双圆括号结构


与let命令很相似,((...)) 结构允许算术扩展和赋值。如,a=$(( 5 + 3 )),将把变量“a”设为“5 + 3”,或者8。

(( a = 23 ))  # C语言风格的变量赋值, "="两边允许有空格.
echo "a (initial value) = $a"

(( a++ ))     # C语言风格的后置自加.
echo "a (after a++) = $a"

(( a-- ))     # C语言风格的后置自减.
echo "a (after a--) = $a"


(( ++a ))     # C语言风格的前置自加.
echo "a (after ++a) = $a"

(( --a ))     # C语言风格的前置自减.
echo "a (after --a) = $a"


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值