bash 变量 赋值及字符串的 操作
bash变量赋值及字符串的操作2010-07-3116:08
变量名:字符串
分配给变量的值可能由一系列的字符组成。这些字符可能是用户输入的字符串,也可能是Linux命令的执行结果。在大多数情况下,需要使用单引号、双引号、反斜线或者反引号来引用变量值。单引号、双引号和反斜线允许用户按不同的方式引用字符串。反引号具有执行Linux命令和使用结果作为命令行参数的特殊功能。
1.引用字符串:双引号、单引号和反斜线
变量值可以由任意字符组成。但是,当用户希望使用被shell用作操作符的字符时,就会出现问题。shell在命令行中使用一些用于计算的元字符。空格用于解析命令行中参数。星号、问号和括弧是用于产生文件名列表的元字符。点符号表示当前的目录。美元符号用于计算变量值,大于符号()和小于符号()是重定向操作符。&符号被用于在后台执行命令,垂直线用来管道输出。如果用户希望把这些字符作为变量值的一部分,首先需要引用这些字符。在一个命令行引用元字符会使它仅仅成为一个字符。不会被shell特殊使用。
可以使用单引号、双引号和反斜线来引用引用这种元字符。使用双引号和单引号可以同时引用多个元字符。单引号或者双引号中的任何元字符都会被引用。反斜线只能引用一个元字符。
如果希望给某变量赋予多个单词,需要引用使用空格分开的这些单词。可以认为给变量分配一个字符串。当然,双引号中的任何其他元字符也会被引用。
在下面的第一个范例中,把双引号用于空格分隔的多个单词。因为空格被包括在双引号中,空格被用作一个普通字符,不再是用于解析命令行中参数的分界符。在第二个例子中,双引号包含一个点,这时候会把点作为一个普通字符。在第三个例子中,星号也被包括在双引号中,星号只做为普通字符使用,而不能用于计算。
$notice="Themeetingwillbetomorrow"$echo$noticeThemeetingwillbetomorrow$message="Theprojectisontime."$echo$messageTheprojectisontime.$notice="Youcangetalistoffileswithls*.c"$echo$noticeYoucangetalistoffileswithls*.c但是,双引号不能引用美元符号,美元操作符被用于计算变量值。
在被双引号包括的美元符号和变量名组合中,美元符号仍旧被用于计算变量值。
变量名会被该变量的值取代,变量值会成为字符串的一部分,而不是变量名成
为字符串的一部分。当希望引号中变量被计算时,可以使用这种方法。在下面
的双引号例子中,winner的名字会被包括在notice中。
$winner=dylan$notice="Thepersonwhowonis$winner"$echo$noticeThepersonwhowonisdylan在另一方面,有时候不希望引号中变量被计算。在这种情况
下,必须使用单引号。单引号不会执行变量计算,把美元符号仅仅视为一个字
符。在下面的范例中,使用单引号可以放置计算winner变量的值。
$winner=dylan$result='Thenameisinthe$winnervariable'$echo$resultThenameisinthe$winnervariable在上述范例中,如果使用双引号,就会发生并
不期望的变量计算。在下面的范例中,字符"$winner"被解释为变量计算。
$winner=dylan$result="Thenameisinthe$winnervariable"$echo$resultThenameisinthedylanvariable通过前置反斜线,就可以引用任何元字符,包括
$操作符。反斜线的用法是引用ENTER键(新行)。当希望计算某字符串中变量,
并且包括$字符时,反斜线非常有用处。在下面的范例中,反斜线被置于$之前,
这样就把$视为一个美元符号:$。同时,变量$winner被计算,因为所使用的双
引号并不引用$操作符。
$winner=dylan$result="$winnerwon$100.00"$echo$resultdylanwon0.002.引用命令:单引号
但是,有时候也许希望在Linux命令中使用单引号。使用单引号,可以把
已经写好的命令赋予一个变量。如果这样做的话,可以把这个变量名用作这个
Linux命令的另一个名称。在命令行上输入$操作符和这种变量名,这样就可以
执行这个命令。在下面的范例中,罗列文件的Linux命令"ls-F"被赋予一个
shell变量。请注意,围绕命令的单引号。当命令行上该shell变量被计算时,
其所包含的Linux命令就会成为命令行参数,并被shell执行。
$lsf='ls-F'$$lsfmydata/reports/letters$实际上,所做的仅仅是给命令
创建另外一个名称,类似于别名。
Bash中的变量
1.用户定义的变量
用户定义的变量有字母数字及下划线组成,并且变量名的第一个字符不能为
数字.
与其它UNIX名字一样,变量名是大小写敏感的.
对于变量,用户可按如下方式赋值:
name=value
在引用变量时,需在前面加$符号,用户也可以在变量间进行相互赋值,如: (前面的$是命令提示符)
$JOHN=john
$NAME=$JOHN
$echoHello$NAMEHellojohn
也可以用变量和其他字符组成新的字,这时可能需要把变量用{}括起,如: $SAT=Satur
$echoTodayis${SAT}dayTodayisSaturday 对于未赋值的变量,Bash以空值对待,用户也可以用unset命令清除给变量 赋的值.
Bash中还可以使用数组变量,其赋值有两种:
(1)name[index]=value
(2)name=(value1.valuen)此时下标从0开始
数组下标的范围没有任何限制,同时也不必使用连续的分量.
Bash中关于变量的内建命令有:
(1)declare和typeset.两者具有一样的功能.其选项有: [-/+]a设置/撤消变量的数组属性
[-/+]i设置/撤消变量的整数属性
[-/+]r设置/撤消变量的只读属性
[-/+]x设置/撤消变量的输出属性
-pvar显示变量属性
(2)export和local.
export把变量输出到环境中,用法为:
exportnameexportname=value 这里需要简单介绍一下export的作用:当Bashshell执行一个 程序时,将首先为该程序建立一个新的执行环境,称为子shell, 在BashShell中变量都是局部的,即它们只是在创建它们的子 Shell中是有意义的,使用export后,变量被设置为全局变量,这 时可以被其它子Shell所识别
local标记变量为局部的(如只能被函数内部使用),用法为:
localnamelocalname=value (3)readonly.
指定变量为只读,执行后,改变量不能被再次赋值,用法为: readonlyname2.位置变量或Shell参数
BashShell在解释用户命令时,将把命令行的第一个子作为命令,而其它字
作为
参数通过位置变量传递给程序.,.,分别代表第一,.,九个参数.其中1-9
是真正的参数名,"$"符只是用来标识变量的替换. 位置变量[message]指命令对应的可执行名. 其它的还有:
$#送给命令的参数个数
$@所有的参数,每个用双括号括起
$*所有的参数,用双括号括起
3.与Shell有关的变量
(1)Shell自身设置的一些常用变量:
LINENO正在执行的命令在脚本中的行号
PWD用户当前目录的全名
OLDPWD最近一次执行cd之前,用户当前目录的全名 PPID父进程ID
$当前进程IDRANDOM随机数(范围0-32767)
SECONDSBashShell的运行时间,单位是秒
REPLYselect和read命令使用,以后会讲到 OPTARGORTIND这两个变量由getopt命令设置 UID当前用户的UserID_上一条命令使用的最后一个参数 (2)影响Shell行为的一些常用环境变量:
PATH命令搜索路径,以冒号为分隔符.注意与DOS下不同的是, 当前目录不在系统路径里
HOME用户home目录的路径名,是cd命令的默认参数 COLUMNS定义了命令编辑模式下可使用命令行的长度 EDITOR默认的行编辑器
VISUAL默认的可视编辑器
FCEDIT命令fc使用的编辑器
HISTFILE命令历史文件
HISTSIZE命令历史文件中最多可包含的命令条数 HISTFILESIZE命令历史文件中包含的最大行数 IFS定义SHELL使用的分隔符
LOGNAME用户登录名
MAIL指向一个需要SHELL监视其修改时间的文件.当该文件修改后,
SHELL将发消息Youhavamail给用户
MAILCHECKSHELL检查MAIL文件的周期,单位是秒
MAILPATH功能与MAIL类似.但可以用一组文件,以冒号分隔,每个文件后 可跟一个问号和一条发向用户的消息
SHELLSHELL的路径名
TERM终端类型
TMOUTSHELL自动退出的时间,单位为秒,若设为0则禁止SHELL自动退出 PROMPT_COMMAND指定在主命令提示符前应执行的命令
PS1主命令提示符
PS2二级命令提示符,命令执行过程中要求输入数据时用
PS3select的命令提示符
PS4调试命令提示符
MANPATH寻找手册页的路径,以冒号分隔
LD_LIBRARY_PATH寻找库的路径,以冒号分隔
bash变量赋值
例子:经常在configure脚本中,会出现以下类似的语句,都表示什么意思
呢?
iftest-
n"${ZSH_VERSION+set}";thenac_env_build_alias_set=${build_alias+set}
test"${ac_configure_args0+set}"!=set
及扩展:
变量赋值方式str没有赋值str为空字符串str为非空字符串备注
var=${str-expr}var=exprvar=$str对var进行设置
var=${str+expr}var=$strvar=expr对var进行设置,var与str要不都取值,要不都不取值。虽然取值不同
var=${str=expr}str=exprvar=exprstr不变
var=$str对var与str进行设置,
var与str保持一致
var=${str?expr}expr输出至stderrvar=str对var进行设置
var=${str:-
expr}var=exprvar=$strvar=${str:+expr}var=var=exprvar=${str:=expr}str=
exprvar=exprstr不变
var=$strvar=${str:?expr}expr输出至stderrBash字符串的操作
(一)字符串的替换
(1)
${变量1/查找字符/替换字符}
(说明一下,这个操作中除了第一个参数是变量外其它两个都是字符;还有一点就是这个操作并不是把"变量1"中的字符替换了,详见例子)
例:
str1=abcABCabc123ABCecho${str1/bcA/aaa}#这里的abc和aaa都是字符串,而str1是变量,并且这个操作过后str1里的字符串长度不会减少,只是产生了一个新的字串。
(2)
${变量1/#查找字符/替换字符}
(说明一下,这个操作上和面的是一样的,只不过是从左边开始匹配,并且
必须从左边第一个字符开始)
例:
echo${str1/#bcA/aaa}#这个例子中并不会把bcA换成aaa因为b不是左边
第一个开头字符
echo${str1/#abc/aaa}#这样才行
(3)
${变量1/%查找字符/替换字符}
(与(2)相反,是结尾最后一个字符要匹配才行)
例:
echo${str1/%3ABC/aaa}#abcABCabc12aaa (3)
${变量1//查找字符/替换字符}
全部替换
(二)取子串
(1)${变量1:位置}
(说明一下,默认是从左边开始,如果"位置"为负数,则是从右边的第"位
置"个字符开始,并且第一个位置为0;从"位置"开始取子串到最后) 例:
str1=abcABCabc123ABCecho${str1:(-3)}#会输出ABC
(2)${变量1:开始位置:结束位置}
(3)如果"变量1"为"*"或"@","位置"所表示的是第几个参数。 (三)字符串移动
字串#匹配字串} (1)${
(说明一下,这个是从左边第一个开始匹配,剥去最短"匹配字串") 例:
str1=abcABCabc123echo${str1#a*c}#输出ABCabc123 (2)${字串##匹配字串}
(说明一下,这个是从左边第一个开始匹配,剥去最长"匹配字串") str1=abcABCabc123echo${str1#a*c}#输出123echo${str1#b*c}#输出
abcABCabc123,因为没有从第一个开始匹配
(3)${字串%匹配字串}
(4)${字串%%匹配字串}
(说明一下,这与上面的(1)(2)是正好相反的,是从最后一个开始匹配的) (四)字符串长度
${#字串}
例:
str=abcdefgecho${#str}#输出7