陈斌彬的技术博客

Stay foolish,stay hungry

Bash - 变量和字符串(原创)

一、内置变量

1.$BASH

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

$ vim test.sh

输入代码:

#!/bin/bash
echo $BASH

运行代码:

$ bash test.sh

img

2.$FUNCNAME

当前函数的名字

$ vim test.sh

输入代码:

#!/bin/bash
xyz23 ()
{
  echo "$FUNCNAME now executing."
  # 正常情况下打印: xyz23 now executing.
  # 在个别版本的bash中,并不支持$FUNCNAME内置变量
}
xyz23
echo "FUNCNAME = $FUNCNAME"        # FUNCNAME =
# 超出函数的作用域就变为null值了.

运行代码:

$ bash test.sh

img

3.$IFS

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

$IFS默认为空白(空格,制表符,和换行符),但这是可以修改的,比如,在分析逗号分隔的数据文件时,就可以设置为逗号,注意 $* 使用的是保存在 $IFS 中的第一个字符。

$ vim test.sh

输入代码:

#!/bin/bash
# $IFS 处理空白与处理其他字符不同.

output_args_one_per_line()
{
  for arg
  do echo "[$arg]"
  done
}
echo; echo "IFS=\" \""
echo "-------"

IFS=" "
var=" a  b c   "
output_args_one_per_line $var  # output_args_one_per_line `echo " a  b c   "`
#
# [a]
# [b]
# [c]

echo; echo "IFS=:"
echo "-----"

IFS=:
var=":a::b:c:::"               # 与上边一样, 但是用" "替换了":".
output_args_one_per_line $var
#
# []
# [a]
# []
# [b]
# [c]
# []
# []

echo
exit 0

程序截图:

img

运行代码:

$ bash test.sh

img

4、$REPLY

当没有参数变量提供给 read 命令的时候,这个变量会作为默认变量提供给 read 命令。也可以用于 select 菜单,但是只提供所选择变量的编号,而不是变量本身的值。在个别版本的 bash 中,并不支持内置变量 $REPLY

$ vim test.sh

输入代码:

#!/bin/bash
# reply.sh
# REPLY是提供给'read'命令的默认变量.
echo
echo -n "What is your favorite vegetable? "
read

echo "Your favorite vegetable is $REPLY."
#  当且仅当没有变量提供给"read"命令时,
# REPLY才保存最后一个"read"命令读入的值.

echo
echo -n "What is your favorite fruit? "
read fruit
echo "Your favorite fruit is $fruit."
echo "but..."
echo "Value of \$REPLY is still $REPLY."
#  $REPLY还是保存着上一个read命令的值,
# 因为变量 $fruit被传入到了这个新的"read"命令中.

echo
exit 0

程序截图:

img

运行代码:

$ bash test.sh

img

二、操作字符串

1.字符串长度

$ vim test.sh

输入代码:

#!/bin/bash

stringZ=abcABC123ABCabc

echo ${#stringZ}                 # 15

程序截图:

img

运行代码:

$ bash test.sh

img

2.使用 awk 来处理字符串

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

例子:提取字符串

$ vim test.sh

输入代码:

#!/bin/bash

String=23skidoo1
#      012345678    Bash
#      123456789    awk
# 注意不同的字符串索引系统:
# Bash的第一个字符是从'0'开始记录的.
# Awk的第一个字符是从'1'开始记录的.

echo ${String:2:4} # 位置 3 (0-1-2), 4 个字符长
# skid

# awk中等价于${string:pos:length}的命令是substr(string,pos,length).
echo | awk '
{
    print substr("'"${String}"'",3,4)      # skid
}
'
#  使用一个空的"echo"通过管道传递给awk一个假的输入,
# 这样就不必提供一个文件名给awk.

exit 0

程序截图:

img

运行代码:

$ bash test.sh

img

三、参数替换

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

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

your_id=${USER}-on-${HOSTNAME}
echo "$your_id"
echo "\$PATH = $PATH"

程序截图:

img

运行:

img

#!/bin/bash
# param-sub.sh

#  一个变量是否被声明或设置,
#+ 将会影响这个变量是否使用默认值,
#+ 即使这个变量值为空(null).

username0=
echo "username0 has been declared, but is set to null."
echo "username0 = ${username0-`whoami`}"
# 不会有输出.

echo

echo username1 has not been declared.
echo "username1 = ${username1-`whoami`}"
# 将会输出默认值.

username2=
echo "username2 has been declared, but is set to null."
echo "username2 = ${username2:-`whoami`}"
#                            ^
# 会输出, 因为:-会比-多一个条件测试.
# 可以与上边的例子比较一下.

程序截图:

img

运行:

img

指定方式                 说明
${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
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
echo "If you are reading this message,"
echo "critical environmental variables have been set."
echo
echo

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

程序截图:

img

运行:

img

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

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