#----------------------------------------------------------#
# ====>
红色字体 -特指煮酒个人所见。加粗则为需要重点注意。 #
# ====>
蓝色加粗 -特指与本文相关人员,包括参与修正的朋友。 #
# ====> 煮酒品茶 -Http://cwtea.blog.51cto.com
#
#----------------------------------------------------------#
变量与算术
Posix Shell为内嵌(inline)算术提供了一种标记法,称为算术展开。Shell会对$((...))里的算术表达式进行计算,再将计算后的结果放回到命令的文本内容。
用途:export用于修改或打印环境变量,readonly则使得变量不得更改,
打印命令的名称以及所有被导出(只读)变量的名称与值,这种方式可使得Shell重新读取输出以便重新建立环境(只读设置)
Posix标准允许你将赋值与命令的操作结合在一起。
unset命令从执行中的shell中删除变量与函数,默认情况下,它会解除变量设置,也可以加上-v来完成。
unset full_name
删除full_name变量
unset -v first middle last
删除其它变量
who |awk '{print $1}' |sort -u 产生排序后的用户列表
env [-i] [var=value ...] [command_name] [arguments...]]
用途:当command_name被env执行时,可针对被command_name继承而来的环境有更细致的控制。
-i 忽略继承的环境,仅使用命令行上所给定的变量与值。
行为:未提供command_name时,显示环境中所有变量的名称与其值。否则,在命令行上使用变量赋值,在引用command_name之前,以修改继承的环境,加上-i选项,env会完全忽略继承的环境,县城只使用所提供的变量与值。
-v 解除(删除)指定的变量,在没有任何选项时,这是默认。
如果没有提供选项,则参娄将视为变量名称,并告知变量已删除,使用-v选项也会发生相同的行为,如使用-f选项,参数则被视为函数名称,并删除函数。
默认情况下,未定义的变量会展开为null字符品,程序随便乱写,就可能会导致灾难发生:
rm -rf /$myprogram 如果未设置myprogram那就完了。 测试是这样的
${varname:=word} 如果varname存在且不是null,则返回它的值,否则,设置它为word,并返回其值。
${varname:?message}如果varname存在且非null,则返回它的值,否则,显示varname:message,并退出当前的命令或脚本。省略message会出现默认的信息parameeter null or not set。
${varname:+word} 如果varname存在且非null,则返回word,否则返回null。
${variable#pattern} 如果模式匹配于变量值的开头处,则删除匹配的最短部分,并返回剩下的部分。
path =/home/tolstoy/mem/long.file.name
${path#/*/} >tolstoy/mem/long.file.name
${path##/*/} >long.file.name 如果模式匹配于变量值的开头处,则删除匹配的最长部分,并返回剩下的部分。
${path%.*} >/home/tolstoy/mem/long.file 如果模式匹配于变量值的结尾处,则删除匹配的最短部分,并返回剩下的部分。
${path%%.*} >/home/tolstoy/mem 如果模式匹配于变量值的结尾处,则删除匹配的最长部分,并返回剩下的部分。
--------------------------------------
[root@localhost test]# cat a
path=/home/tolstoy/mem/long.file.name
[root@localhost test]# ./a
./a: line 2: tolstoy/mem/long.file.name: Permission denied 已经匹配,要替换则用上替换运算符。
/home/tolstoy/mem/long.file.name
---------------------------------------
解释:SHell脚本的命令行参数,同时也表示在Shell函数内的函数参数。它们的名称是以单个整数来命令,出于历史原因,当这个整数大于9时,就应该以花括号({})括起来。
$#
供传递到Shell脚本或函数的参数总数。当你是为了处理选项和参数而立的循环时,它会很有用。
$*,$@
一次表示所有的命令行参数,这两个参数可用来把命令行参数传递给脚本或函数所执行的程序。
"$*"
将所有命令行参数视为单个字符串,等同于“$1 $2...”$IFS的第一个字符用来作为分隔字符,以分隔不同的值来立字符串。
printf "The arguments were %s\n" "$*"
"$@" 将所有命令行参数视为单独的个体,也就是单独的字符串,等同于"$1" "$2"...这是将参数传递给其它程序的最佳方式,因为它会保留所有内嵌在每个参数里的任何空白。例:
set命令可以做的事很多,调用此命令而未给预任何选项,则它会设置位置参数的值,并将之前存的任何值丢弃。
解释:shift命令是用来截去来自列表的位置参数,由左开始,一旦执行shift,$1的初始值会永远消失,取而代之的是$2的旧值,$2的值,变成$3的旧值,以此类推,$#值则会依次减1,shift也可使用一个可选的参数,也就是要位移的参数的计数,单纯的Shift等同于shift 1。
------------------------------------
[root@localhost test]# cat a
set -- hello "hi there" greetings
#echo there are $# total arguments
[root@localhost test]# ./a
I is hello hi there greetings
-----------------------------------
煮酒品茶:$@与$*都是单个拆开,而"$@"是不将""里的内容拆开,"$*"把所有的内容做一个整体,再将他们的值赋于变量。 Shell还有很多额外的内置变量,有一些也具有单一字符,非文字或数字字母的名称,其他则是全由大写字母组成的名称。
------------------------------------------------------
@,传递给当前进程的参数。置于双引号内,会展开为个别参数。
*,传递给当前进程的命令行参数,置于双括号内,展开时为一单独参数。
!,最近一个后台命令的PID。可以此方式存储进程编号,然后通过wait命令同步。
IFS,内部的字段分隔符,一般为制表符、空格、以及换行符。
LC_ALL,当前locale的名称。会覆盖LANG与其他LC_*变量。
LC_CTYPE,在模式匹配期间,用来确定字符类别的当前locale名称。
LINENO,刚执行过的行在脚本或函数内的行编号。
NLSPATH,在$LC_MESSAGES(XSI)所给定的信息语言里,信息目录的位置。
PS4,以set -x设置的执行跟踪的提示字符串,默认为“+”。
-----------------------------------------------------
---------------------------------------------
— %:取模运算,第一个变量除以第二个变量求余数。
— -=:减等于,在第一个变量的基础上减去第二个变量。
— *=:乘等于,在第一个变量的基础上乘以第二个变量。
— /=:除等于,在第一个变量的基础上除以第二个变量。
— %=:取模赋值,第一个变量对第二个变量取模运算,再赋值给第一个变量。
---------------------------------------------------------------
-----------------------------
[root@localhost test]# cat ys
[root@localhost test]# ./ys
-----------------------------
解释:每条命令,不管是内的shell函数还是外部的,当它退出时,都会返回一个小的整数值给引用它的程序,即为退出状态。
[root@localhost test]# echo $?
[root@localhost test]# lss foo
-bash: lss: command not found
[root@localhost test]# echo $?
---------------------------
>0
在重定向或单词展开期间(~,变量,命令、算术展开,以及单词切割)失败。
------------------------------
用途:目的是从Shell脚本返回一个退出状态给脚本的调用者。
行为模式:如果没有提供,则以最后一个执行命令的退出状态作为默认的退出状态,如果这就是你要的,则最好明白地在shell脚本里这么写 exit $?
----------------------------
statements-if-true-2 ...]
statements-if-all-else-fails ]
-------------------------
解释:test命令可以处理shell脚本里的各烊工作,它产生的不是一般输出,而是可使用的退出状态。test接受各种不同的参数,它控制它要执行的哪一种测试。
test命令有另一种形式:[...],这各用法的作用完全与test命令一样。
if test "$str1"= "str2" 与if ["$star1"="str2"]一样。
用途。为了测试shell脚本里的条件,通过退出状态返回其结果,要特别注意的是:这个命令的第二种形式,方括号根据字面意义靛字的输入,且必须与括起来的expression以空白隔开。
在XSI兼容的系统里,它的表达式可以与-a(逻辑的AND)与-o(逻辑的OR)结合使用。
注: if [ -f "$file" ] 必须加引号
if [ "X$answer" = "Xyes" ] ... 新时代的用法。
-----------------------------
[root@localhost test]# cat test
if [ -f "$file" ] && [ -w "$file" ]
echo $0: $file is not writable, giving up. >&2
[root@localhost test]# ./test
++ '[' -f /root/test/a ']'
++ '[' -w /root/test/a ']'
++ echo ./test: /root/test/a is not writable, giving up.
./test: /root/test/a is not writable, giving up.
----------------------------------------
-------------------------------
要测试的值出现在case与in之间,发现匹配的时候,便执行相对应的程序代码,直至;;为止。可以使用多个模式,只要用|字符加以分隔时可,模式里会包含任何的shell通配字符,且变量,命令与算术替换会在它用作模式匹配之前在此值上被执行。
不同之处:对待condition的退出状态,只要condition是成功退出,while会继续循环,只要condition未成功结束,until则执行循环。until在等待某个事件发生,它就很有作用。
什么命令都不必做,只是成功地巡视出,用于编写无限循环。即会永久执行的循环。
continue用于提早开始下一段重复的循环操作,也就是在到达循环体的底部之前。
break与continue命令都接受可选的数值参数,可分别用来指出要中断(break)或继续多少个被包含的循环。
shift:用来处理命令行参数的时候,一次向左位移一位(或更多位),默认为1
语法:getopts option_spec variable [ arguments ... ]
用途:简化参数处理,并且让shell脚本可以轻松地匹配于posix参数处理惯例。
解释:是指一段单独的程序代码,用以执行一些定义完整的单项工作。
注意:在shell函数体里使用exit,会终止整个shell脚本。
语法: return [ exit-value ]
用途:返回由shell函数得到的退出值给调用它的脚本。
总结:特珠变量、运算符、if for while until test return getopts shift $.