# Shell变量 ## 位置变量 ``` $command arg1 arg2 arg3 $0 命令本身(shell文件名) $1 第1个命令行参数 $2 第2个命令行参数 $n 第n个命令行参数 ``` ## 预定义变量 ``` $# 传入脚本的命令行参数的个数 $* 所有命令行参数值,各参数值之间用IFS中的第一个字符分隔开 $@ 与$*类似 $! 上一个后台命令对应的进程号 $? 最近一条命令执行成功后的退出状态 $$ 当前进程号 ``` `$*与$@的差异`: `$*` `$@` 都表示参数列表, `$*` 与 `$@` 相同, 但`"$*"` 与 `"$@"` 不同. `"$*"` : 将所有参数解释为一个字符串 `"$@"` : 是一个参数数组 例1: $ cat test1.sh ``` #!/bin/sh echo -n "\$* is: " for arg in "$*" do echo $arg done ``` 执行结果: ``` $ ./test.sh -f getopts.sh -v -prefix=/home $* is: -f getopts.sh -v -prefix=/home ``` 例2: $ cat test2.sh ``` #!/bin/sh echo "\$@ is: " for arg in "$@" do echo $arg done ``` 执行结果: ``` $ ./test.sh -f getopts.sh -v -prefix=/home $@ is: -f getopts.sh -v -prefix=/home ``` ## IFS IFS是内部域分隔符(Internal Filed Seprator)的缩写. 默认值为 "space table newline" 查看IFS的值: 直接输出IFS是看不到的,将它转换为二进制就可以看到了,例如: ``` $ echo "$IFS" | od -b 0000000 040 011 012 012 其中040表示空格,011表示tab, 012表示换行符\n, 最后一个012是因为echo默认是会换行的 ``` IFS对空格的空白处理: 左右两边的空白被忽略,多个连续的空白被当成一个IFS处理 `$*`使用IFS中的第一个字符(space) 下面通过一个实例来演示IFS的用法和作用: (代码来自于"笑遍世界"的博客 http://smilejay.com/2011/12/bash_ifs/) ``` #! /bin/bash #author: Jay Ren #date: 2011.12.10 echo "----------------------------------IFS test--------------------------------" echo "default \$IFS is:(ASSII in hexadecimal value)" echo -n "$IFS" | xxd -g 1 | awk -F":" '{print $2}' | awk -F" " '{print $1, $2, $3}' echo "by default, IFS should be a SPACE, a HORIZONTAL TAB, or a LINC FEED." function output_args_one_per_line() { arg_list=$* echo "\$*='$*'" for arg in $arg_list do echo "[$arg]" done } echo "--------------------------------------------------------------------------" echo "set IFS=' ' #dealing with SPACE in IFS is different with other chars." echo "var=' a b c '" IFS=' ' var=" a b c " output_args_one_per_line $var echo "--------------------------------------------------------------------------" echo "set IFS=':'" echo "var='::a:b::c:::'" IFS=':' var="::a:b::c:::" output_args_one_per_line $var echo "--------------------------------------------------------------------------" echo "set IFS='+:-;' #but \$* just use 1st char in IFS as the separator." echo "var='::a:b::c:::'" IFS='+:-;' var="::a:b::c:::" output_args_one_per_line $var echo "--------------------------------------------------------------------------" echo "set IFS='-+:;' #but \$* just use 1st char in IFS as the separator." echo "var='::a:b::c:::'" IFS='-+:;' var="::a:b::c:::" output_args_one_per_line $var echo "--------------------------The END of IFS test-----------------------------" ``` 输出结果如下: ``` ----------------------------------IFS test-------------------------------- default $IFS is:(ASSII in hexadecimal value) 20 09 0a by default, IFS should be a SPACE, a HORIZONTAL TAB, or a LINC FEED. -------------------------------------------------------------------------- set IFS=' ' #dealing with SPACE in IFS is different with other chars. var=' a b c ' $*='a b c' [a] [b] [c] -------------------------------------------------------------------------- set IFS=':' var='::a:b::c:::' $*='::a:b::c::' [] [] [a] [b] [] [c] [] -------------------------------------------------------------------------- set IFS='+:-;' #but $* just use 1st char in IFS as the separator. var='::a:b::c:::' $*='++a+b++c++' [] [] [a] [b] [] [c] [] -------------------------------------------------------------------------- set IFS='-+:;' #but $* just use 1st char in IFS as the separator. var='::a:b::c:::' $*='--a-b--c--' [] [] [a] [b] [] [c] [] --------------------------The END of IFS test----------------------------- ```