1. 普通变量
1.1 统计计算机的软硬件信息
案例:
#!/bin/bash
#使用便利替换定义若干个变量
TIME=`date`
NAME=`uname -n`
KERNEL=`uname -s`
VERSION=`uname -r`
ARCH=`uname -m`
OS=`uname -o`
echo
echo " Info about your computer"
echo " =============================="
echo " Current Time: $TIME"
echo " Host Name: $NAME"
echo " Operating System: $OS"
echo " Computer ARCH: $ARCH"
echo " Kernel Version: $KERNEL $VERSION"
echo
exit 0
Shell脚本中定义变量的语法格式:
NAME=value
注意:定义变量的等号两侧不能有空格;变量的名字只能包含大小写字母、数字和下划线_,并且只能以字母或下划线开头;
1.2 如果变量的值是来至于脚本运行后,用户的输入数据
可以使用read命令把用户的输入赋值给变量,使用unset命令删除一个定义过的变量。
read –p “promptinfomation” variable1 variable2 ….
案例:
#!/bin/bash
echo
read -p " Please input your name:" NAME
echo -e " Welcome,$NAME! \n Your name is saved in variable 'NAME'!"
echo "------------------"
echo
echo " Clear variable 'NAME' using 'unset' command."
#清除变量的值
unset NAME
echo
echo " Now variable 'NAME' is:"
#判断变量是否被清除
if [ -z $NAME ]
then
echo
echo " NAME:$NAME"
echo " Variable NAME is null."
else
echo
echo " NAME:$NAME"
echo " Variable NAME is not null"
fi
echo
echo " quit"
echo
exit 0
1.3 把变量定义为一个只读常量
案例:
#!/bin/bash
VERSION=2.0
#声明变量VERSION是一个只读变量
readonly VERSION
echo
echo -e " Defined readonly variable:\n VERSIN=$VERSION"
echo
#尝试修改一个只读变量,会失败
echo " Try to modify readonly variable VERSION"
VERSION=3.0
echo
echo -e " Readonly variable VERSION doesn't change, \n VERSION=$VERSION"
exit 0
2. 数组变量
一个变量保存多个值
案例:
#!/bin/bash
#数组元素从0开始
index=0
#从passwd文件中取出所有用户
#指定分隔符为磨耗,使用cut命令从passwd文件的每一行中提取出用户名
for i in `cut -f 1 -d: /etc/passwd`
do
#把每一个用户名赋值给user数组的元素
user[$index]=$i
echo user[$index]
#每赋值一个用户后,把索引值加一
let index=$index+1
done
#重复使用变量index作为行号
index=1
#使用字符@分隔所有的数组元素
#如果没有使用双引号引用,使用星号${user[*]}也可以
for name in "${ user[@] }"
do
echo " $index:$name"
#行号加一
let index=$index+1
done
echo "---------------"
echo " Print all users in one line:"
echo
#把所有的数组元素作为一个整体进行打印
echo "${ user[*] }"
#把数组元素作为单个的个体进行打印
echo
echo "---------------"
#对user数组重新赋值,前50个元素将会丢失
#即使没有明确地覆盖它们
echo " Reassign the user array,the user names will be lost:"
user=([50]=zhangze,emma,patrick)
echo
echo ${ user[*] }
echo
exit 0
语法:
array[index]=value
3. 环境变量
在Shell脚本中如何创建环境变量,从而使得子进程可以访问这些变量呢?
把一个变量放到环境中这个过程通常叫做导出一个变量,Shell中定义并导出一个变量的方法为:
name=value;exportname
或者
export name=value
案例:
parent.sh内容如下:
#!/bin/bash
#检查是否指定了命令行选项--export
#[]中的字符需要与[]空格开
if [ "$1" = "--export" ]
then
#在父进程中定义全局变量
export LOCATION=USA
elif [ "$1"="--no-export" ]
then
#在父进程中定义一个本地变量
LOCATION=USA
else
#显示本脚本的使用方法
echo
echo -e "`basename $0` --export\texport parent process's variable to child process"
echo -e "`basename $0` --no-export\tdon't export parent process's variable to child process"
echo
exit 0
fi
echo
echo "Your parent is at $LOCATION."
#创建子进程,子进程是否能够得到LOCATION变量的拷贝依赖于export关键字
./child.sh
#子进程退出,父进程继续运行
echo
echo -e "Your parent is at '$LOCATION'."
echo -e "Child process and parent process have different LOCATION."
echo
exit 0
child.sh内容如下:
#!/bin/bash
#检查子进程中是否有父进程中变量LOCATION的拷贝
echo "-----------------------"
echo " The child is at '${LOCATION:-somewhere not defined}'."
#如果子进程中拥有变量LOCATION的拷贝,就修改它,如果没有就定义它
LOCATION=CHINA
#访问子进程中的变量LOCATION
echo
echo " The child is at '$LOCATION'."
echo "------------------------------"
exit 0
4. Shell变量
除了我们自己在脚本中创建的本地变量和环境变量以外,Shell在启动过程中还会设置一些特殊的变量来帮助Shell正确运行,这些变量叫做Shell变量。
例如:HOME、SHELL、USER等等。
5. 特殊变量
除了前面介绍的变量,还有一些具有某些特殊功能的特殊变量,它们由Shell创建并只能被Shell修改。
特殊变量:
$0:表示脚本本身
$1、$2、$3依次是脚本后面的选项或参数的值
$@:表示从$1、$2、$3...的参数
$#:表示除$0外的所有参数的个数
$?:表示shell返回的状态
5.1 实现一个显示文本文件内容的脚本,可以通过命令行参数来告知脚本我们所希望操作的文件
案例:
#!/bin/bash
#检查是否指定了参数
if [ -n "$1" ]
then
echo
#显示脚本文件名及脚本如何被调用
echo -e " Script Name:\t\t\t`basename $0`"
echo -e " How Script is invoked:\t\t$0 $1"
#显示指定的参数
if [ -f "$1" ]
then
echo
echo "The content of file '$1':"
echo "---------------------------"
#显示命令行指定的参数文件的内容
echo "`cat $1`"
echo "---------------------------"
else
echo " File $1 don't exist."
exit 1
fi
else
#如果没有指定参数,显示帮助信息
echo
echo "Show the content of a file"
echo
echo " Usage."
echo " `basename $0` [filename]"
echo " $0 [filename]"
fi
echo
exit 0
5.2 如果用户执行脚本时,每一次所指定的参数个数都不固定。
案例:
#!/bin/bash
#如果没有指定文件
#使用if[-z $1]也可以达到同样的效果
if [ $# -eq 0 ]
then
echo
echo "Usage:`basename $0` [filename]..."
echo "At least specify one filename to remove execute permission for group and others."
exit 0
fi
echo
#检查是否有其他的参数
#使用until [ -z $1 ]可以达到同样的效果
while [ $# -gt 0 ]
do
echo "Processing file '$1'."
chmod go-x $1
#删除第一个参数
shift
done
echo "Done"
echo
exit 0
shift命令:
1 shifit 删除一个参数
2 shifit n 删除n个参数
3 shift “$#” 删除所有参数
4 shift $(($# -3)) 删除除了最后的3个位置参数外的所有参数。
5.3 除了特殊变量$#和shift命令组合实现参数动态变化,还有$@和$*
案例:
#!/bin/bash
#如果没有指定文件
#使用if[-z $1]也可以达到同样的效果
if [ $# -eq 0 ]
then
echo
echo "Usage:`basename $0` [filename]..."
echo "At least specify one filename to remove execute permission for group and others."
echo
exit 1
fi
echo
echo "You specified the following parameters:"
echo " <<$*>>"
echo
#遍历所有参数
for PARAMETER in "$@"
do
echo " Processing file '$PARAMETER'."
#删除权限
chmod go-x $PARAMETER
done
echo " Done"
exit 0
由于变量$@和$*代表了完整的参数列表,所以在用while循环检查是否还有剩余的参数等待处理时,还可以使用如下形式:
while [ “$@” != “”] 或者 while [ -n “$@” ]
while [ “$*” != “”] 或者 while [ -n “$*” ]
5.4 查看上个命令是否成功,再根据结果采取不同的操作
案例:
#!/bin/bash
NEWDIR=~/newdir
NEWFILE=newfile
#指定log文件为special.pid.log
LOGFILE=`basename $0 .sh`.$$.log
#在主目录下创建一个目录fin
mkdir $NEWDIR
if [ $? -eq 0 ]
then
#成功地创建log目录
echo "`date`:Creating Directory '$NEWDIR' succeed."
#在log目录中创建log文件
echo " `date`:Creating Directory '$NEWDIR' succeed." >> $LOGFILE
#改变当前工作目录为~、newdir
cd $NEWDIR
if [ $? -eq 0 ]
then
echo "`date`:Changing Current Directory to '$NEWDIR' succeed."
#当前工作目录改变,因此使用OLDPWD
echo "`date`:Changing Current Directory to '$NEWDIR' succeed." >> $OLDPWD/$LOGFILE
#然后创建一个新的文件
touch $NEWFILE
if [ $? -eq 0 ]
then
echo "`date`:Creating newfile in directory '$NEWDIR' succeed."
#当前工作目录改变,因此使用OLDPWD
echo "`date`:Creating newfile in directory '$NEWDIR' succeed." >> $OLDPWD/$LOGFILE
else
#$? != 0 意味着失败
echo "`date`:Creating newfile in directory '$NEWDIR' failed."
#当前工作目录改变,因此使用OLDPWD
echo "`date`:Creating newfile in directory '$NEWDIR' failed." >> $OLDPWD/$LOGFILE
fi
else
#$? != 0 意味着失败
echo "`date`:Changing Current Directory to '$NEWDIR' failed."
#当前工作目录改变,因此使用OLDPWD
echo "`date`:Changing Current Directory to '$NEWDIR' failed." >> $OLDPWD/$LOGFILE
fi
else
#$? != 0 意味着失败
echo "`date`:Creating directory '$NEWDIR' failed."
echo "`date`:Creating directory '$NEWDIR' failed." >> $LOGFILE
fi
echo "Please check log file $LOGFILE."
echo
exit 0
变量$?:在Unix/Linux系统中,每一个命令或脚本在结束运行后都会返回一个0到255之间的数值,用来表示是否成功执行,这个数值被Shell保存在特殊变量$?中。数值0通常用来表示成功执行,而1或1以上的其他数字则代表失败和各种各样的错误。
注意:
1 当位置变量大于或等于10后,必须使用花括号,如{10}。这样,Shell不会当成位置变量$1+0
2 不可以该表位置变量的值,且普通变量不能以数字开头
3 在for循环遍历完整的参数列表时,应该使用$@而不是$*