目录

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-----------------------------