本文共 9449 字,大约阅读时间需要 31 分钟。
如何设定变量,引用
1 2 3 4 5 6 7 | [root@nono ~] # ANIMAL=pig #定义变量值 [root@nono ~] # echo "There are some $ANIMALs." # {}也可以引用变量 There are some . [root@nono ~] # echo "There are some ${ANIMAL}s." # 双引号弱引用,替换变量 There are some pigs. [root@nono ~] # echo 'There are some ${ANIMAL}s.' # 单引号强引用,不做变量替换 There are some ${ANIMAL}s. |
脚本在执行时会启动一个子shell进程
命令行中启动的脚本会继承当前shell环境变量
系统自动执行的脚本(非命令行启动)就需要自我定义需要各环境变量
如何设定本地变量,环境变量
本地变量:
VARNAME=VALUE 作用域为整个bash进程
局部变量:
local VARNAME=VALUE 作用域为当前代码段
环境变量:
export VARNAME=VALUE 作用域为当前shell进程及其子进程
VARNAME=VALUE
export VARNAME
位置变量: $1,$2....., shift
特殊变量: $? : 上一个命令的执行状态返回值
程序执行,可能有两类返回值
程序执行结果
程序状态返回代码 ( 0-255 )
0 : 正确执行
1-255 : 错误执行 1 , 2 , 127 系统预留
撤销变量: unset VARNAME
1 2 3 4 5 | [root@nono ~] # name=zhao #定义变量 name=zhao [root@nono ~] # echo $name zhao [root@nono ~] # unset name #取消变量 [root@nono ~] # echo $name #取消成功 |
查看当前shell中的变量 ( 包括本地变量和环境变量 )
1 | [root@nono ~] # set |
查看当前shell中的环境变量
1 2 3 | [root@nono ~] # printenv [root@nono ~] # env [root@nono ~] # export |
给变量添加变量值
1 2 3 4 5 | [root@nono ~] # echo $ANIMAL pig [root@nono ~] # ANIMAL=$ANIMAL:goat #在变量 ANIMAL 基础上添加变量 [root@nono ~] # echo $ANIMAL pig:goat |
/dev/null : 软件设备, bit bucket 数据黑洞
1 2 3 | [root@nono ~] # id root &> /dev/null [root@nono ~] # echo $? 0 |
练习: 写一个脚本,完成以下任务
1 . 添加5个用户,user1,...,user5
2 . 每个用户的密码同用户名,而且要求,添加密码完成后不显示命令passwd的执行结果信息
3 . 每个用户添加完成后,都要显示用户某某已经成功添加
1 2 3 4 | #!/bin/bash useradd user1 echo "user1" | passwd --stdin user1 &> /dev/null echo "add user1 successfully." |
练习: 写一个脚本,完成以下任务
1 . 使用一个变量保存一个用户名
2 . 删除此变量中的用户,且一并删除其家目录
3 . 显示"用户删除完成"类的信息
1 2 3 4 5 6 | #!/bin/bash zhao=user2 useradd ${zhao} #echo "useradd $zhao 0k" userdel -r ${zhao} echo "userdel finish." |
变量名称:
1 . 只能包含字母,数字和下划线,并且不能数字开头
2 . 不应该跟系统中已有的环境变量重名
3 . 最好做到见名知义
bash中如何实现条件判断
条件测试类型
整数测试
字符测试
文件测试
条件测试的表达式
[ expression ]
` expression `
test expression
整数比较
-eq : 测试两个整数是否相等.比如 $A -eq $B
-ne : 测试两个整数是否不等.不等为真,等于为假
-gt : 测试一个数是否大于另一个数.大于为真,否则为假
-lt : 测试一个数是否小于另一个数.小于为真,否则为假
-ge : 大于或等于
-le : 小于或等于
命令间的逻辑关系
逻辑与 : && 全部为真才为真
第一个条件为假时,第二条件不用再判断,最终结果为假
第一个条件为真时,第二条件必须得判断,若第二个条件为真才为真,第二个条件为假就为假
逻辑或 : || 一个为真则为真
第一个条件为假时,判断第二个条件,第二个条件若为真则为真,为假则为假
第一个条件为真时,第二个条件不在判断,最终结果为真
练习 : 如果用户user6不存在,就添加用户user6
1 2 | ! id user6 && useradd user6 # ! 为结果取反. ! id user6 意思是如果用户不存在 &&(逻辑与) 则判断下一条命令 id user6 || useradd user6 #如果 user6 存在(判断条件为真) ||(逻辑或) 则不在运行下一条命令 |
练习 : 判断 /etc/inittab 文件中有多少行,若大于100行则显示为 big file 否则显示 small file
1 2 3 4 5 6 | #!/bin/bash LINES=` wc -l /etc/inittab ` # `wc -l /etc/inittab` 命令引用 #echo $LINES FINLINES=` echo $LINES | cut -d ' ' -f1` #echo $FINLINES [ $FINLINES -gt 100 ] && echo "/etc/inittab is a big file." || echo "/etc/inittab is a small file." |
练习 : 如果用户存在,就显示用户已存在;否则,就添加此用户
id user1 && echo "user1 exists." || useradd user1
练习 : 如果用户不存在,就添加.否则,显示其已经存在
! id user1 && useradd user1 || echo "user1 exists."
练习 : 如果用户不存在,就添加用户并且给密码;否则,显示其已经存在
! id user1 && useradd user1 && echo "user1" | passwd --stdin user1 || echo "user1 exists."
练习 : 写一个脚本,完成以下要求
1. 添加 3 个用户 user1 , user2 , user3; 但要要求判断用户是否存在,不存在而后再添加
2. 最后显示当前系统上共有多少个用户
! id user1 &> /dev/null && useradd user1 && echo "user1" | passwd --stdin user1 &> /dev/null || echo "user1 exists."
! id user2 &> /dev/null && useradd user2 && echo "user1" | passwd --stdin user2 &> /dev/null || echo "user2 exists."
! id user3 &> /dev/null && useradd user3 && echo "user1" | passwd --stdin user3 &> /dev/null || echo "user3 exists."
USERS=`wc -l /etc/passwd | cut -d: -f1`
echo "$USERS users."
练习:写一个脚本,完成以下要求
给定一个用户 : 1 . 如果其 UID 为 0 , 就显示为此管理员 2 . 否则,就显示其为普通用户
1 2 3 4 | #/bin/bash NAME=user1 USERID=` id -u $NAME` # id -u 判断 UID [ $USERID - eq 0 ] && echo "Admin" || echo "Common user." |
使用 if 语句完成 (单分支 if 语句)
1 2 3 4 5 6 7 8 | #!/bin/bash NAME=user1 USERID=` id -u $NAME` if [ $USERID - eq 0 ]; then echo "Admin." else echo "Common user." fi |
条件判断,终止结构
单分支 if 语句
if 判断条件; then
statement1
statement2
....
fi
例: (单分支语句) 判断 user1 用户是否存在,如果存在则显示用户已存在
#!/bin/bash
NAME=user1
if id $NAME &> /dev/null; then
echo "$NAME exists."
fi
双分支的 if 语句
if 判断条件; then
statement1
statement2
...
else
statement3
statement4
...
fi
例: (双分支语句) 如果用户 user1 存在,则显示用户已存在,否则显示用户不存在
1 2 3 4 5 6 7 | #!/bin/bash NAME=user1 if id $NAME &> /dev/null ; then echo "$NAME exists." else echo "$NAME not exists." fi |
例: (双分支语句) 如果用户 user1 存在,则显示用户已存在,否则添加用户 user1
1 2 3 4 5 6 7 8 9 | #!/bin/bash NAME=user1 if id $NAME &> /dev/null ; then echo "$NAME exists." else useradd $NAME echo "$NAME" | passwd --stdin $NAME &> /dev/null echo "Add $NAME finished." fi |
多分支的 if 语句
if 判断条件1; then
statment1
....
elif 判断条件2; then
satment2
...
elif 判断条件3; then
statment3
...
else
statment4
...
fi
测试脚本是否有语法错误:
bash -n 脚本名称
bash -x 脚本名称; 单步执行
定义脚本退出状态码
exit: 退出脚本
exit: #
文件测试 :
-e FILE : 测试文件是否存在
-f FILE : 测试文件是否为普通文件
-d FILE : 测试指定路径是否为目录
-r FILE : 测试当前用户对指定文件是否有读权限
-w FILE : .... 写权限
-x FILE : .....执行权限
练习 : (多分支 if 语句)
给定一个文件: 如果是一个普通文件,就显示之. 如果是一个目录,就显示之. 否则,此为无法识别之文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #!/bin/bash FILE= /etc/inittab if [ ! -e $FILE ]; then #如果文件不存在 echo "No such file" exit 9 fi if [ -e $FILE ]; then echo "Common file." elif [ -d $FILE ]; then echo "Directory." else echo "Unknow." fi |
练习: 判断当前系统上是否有用户的默认shell为bash; 如果有,就显示有多少个这类用户;否则,就显示没有这类用户;
1 2 3 4 5 6 7 8 9 | #!/bin/bash grep "\<bash$" /etc/passwd &> /dev/null #找到以 bash 为单词结尾的行,输出命令不要 RETVAL=$? if [ $RETVAL - eq 0 ]; then USERS=` grep "\<bash$" /etc/passwd | wc -l` echo "The shells of $USERS users is bash." else echo "not such user." fi |
练习 : 判断当前系统上是否有用户的默认shell为bash;如果有,就显示用户名;否则,就显示没有这类用户;
1 2 3 4 5 6 7 8 9 | #!/bin/bash grep "\<bash$" /etc/passwd &> /dev/null REVAEL=$? if [ $REVAEL - eq 0 ]; then USERNAME=` grep "\<bash$" /etc/passwd | cut -d: -f1` echo "$USERNAME" else echo "not user." fi |
练习 : 给定一个用户,判断其用户UID于GID是否一样.如果一样,就显示为"good guy";否则,就显示此用户为"bad guy"
写法一
1 2 3 4 5 6 7 8 9 | #!/bin/bash USER=user1 USERUID=` id -u $USER` USERGID=` id -g $USER` if [ $USERUID - eq $USERGID ]; then echo "good guy." else echo "bad guy." fi |
写法二
1 2 3 4 5 6 7 8 9 10 11 12 13 | #!/bin/bash USERNAME=user1 if ! grep "^$USERNAME" /etc/passwd &> /dev/null ; then echo "No such user: $USERNAME." exit 8 #首先需要判断 user1 是否存在,如果不存在则退出 fi USERUID=` grep "^$USERNAME" /etc/passwd | cut -d: -f3` USERGID=` grep "^$USERNAME" /etc/passwd | cut -d: -f4` if [ $USERUID - eq $USERGID ]; then echo "Good guy" else echo "Bad guy" fi |
练习 : 查找 /etc/inittab 下有没有空白行,如果有是多少行
1 2 3 4 5 6 7 8 9 10 11 | #!/bin/bash FILE= /etc/inittab if [ ! -e $FILE ]; then #首先判断 /etc/iniitab 是否存在 echo "No such file." exit 8 fi if grep "^$" /etc/inittab &> /dev/null ; then echo "Total blank lines:`grep " ^$ " $FILE | wc -l`." else echo "No blank line." fi |
shell 中如何进行算术运算
A=3 B=6
1 . let 算术运算表达式
let C=$A+$B
2 . $[算术运算表达式]
C=$[$A+$B]
3 . $((算术运算表达式))
C=$(($A+$B))
4 . expr 算术运算表达式,表达式中各操作数及运算符之间要有空格,而且要使用命令引用
C=`expr $A + $B `
练习 : 给定一个用户,获取其密码警告期限,而后判断用户密码使用期限是否已经小于警告期限
如果小于,则显示"Warning" 否则显示"OK"
1 2 3 4 5 6 7 8 9 10 11 12 | #!/bin/bash W=` grep "student" /etc/passwd | cut -d: -f6` #首先获取 students 的密码警告期限 S=` date +%s` #获取绝对秒数 T=` expr $S /86400 ` #绝对秒数除以每天的秒数86400,计算现在的时间 L=` grep "student" /etc/shadow | cut -d: -f5` # f5为多少天内必须密码 N=` grep "student" /etc/shadow | cut -d: -f3` # f3为上次修改密码的日期 SY=$[$L-$[$T-$N]] if [ $SY -lt $W ]; then echo "Worning." else echo "OK." fi |
位置变量 : # ./filetest.sh /etc/fstab /etc/inittab
$1 : /etc/fstab
$2 : /etc/inittab
练习 : 写一个脚本 (位置变量)
能接受一个参数(文件路径) 判定 : 此参数如果是一个存在的文件,就显示"OK.",否则就显示"No such file."
1 2 3 4 5 6 | #!/bin/bash if [ -e $1 ]; then echo "OK." else echo "No such file." fi |
[root@nono ~]# ./file3.sh /etc/inittab #文件存在
OK.
[root@nono ~]# ./file3.sh /etc/inittabbb #文件不存在
No such file.
特殊变量:
$? 退出状态码
$# 参数的个数
$* 参数列表
$@ 参数列表
练习 : 写一个脚本 (位置变量) 能接受一个参数 (文件路径)
1 2 3 4 5 6 7 8 9 10 11 12 | 判定 : 此参数如果是一个存在的文件,就显示 "OK." ,否则就显示 "No such file." 如果没有跟参数,则提示用户追加参数 #!/bin/bash if [ $ # -lt 1 ]; then # $#为参数的个数,若参数的个数小于1,则提示用户.下面程序不再进行 echo "Usage: ./file3.sh ARG1 [ARG2...]" exit 4 fi if [ -e $1 ]; then echo "OK." else echo "No such file." fi |
[root@nono ~]# ./file3.sh
Usage: ./file3.sh ARG1 [ARG2...]
位置变量 shift 的使用
#!/bin/bash
echo "$1"
shift
echo "$1"
shift
echo "$1"
shift
[root@nono ~]# ./shift.sh 1 2 3
1
2
shift 替换使用
#!/bin/bash
echo "$1"
shift 2
echo "$1"
shift 2
echo "$1"
[root@nono ~]# ./shift.sh 1 2 3 4 5
1
3
5
练习 : 写一个脚本 给脚本传递两个参数(整数); 显示此两者之和,之积
1 2 3 4 5 6 7 | #!/bin/bash if [ $ # -lt 2 ]; then echo "Usage: he.sh ARG1 ARG2." exit 8 fi echo "The sum is : $(($1+$2))." echo "The prod is : $(($1*$2))." |
字符测试
== : 测试是否相等 , 相等为真 , 不等为假
!= : 测试是否不等 , 不等为真 , 相等为假
-n string : 测试指定字符串是否为空 , 空则真 , 不空则假
-z string : 测试指定字符串是否不空 , 不空为真 , 空为假
练习 : 传递一个用户名参数给脚本,判断此用户的用户名跟基本组的组名是否一致,并将结果显示出来
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #!/bin/bash if [ $ # -lt 1 ]; then #如果用户没有输入: 用户名 则退出 echo "NO user." exit 4 fi if ! id $1 &> /dev/null ; then #如果用户输入的用户名不存在,则显示 : No such user echo "No such user." exit 9 fi if [ ` id -n -u $1` == ` id -n -g $1` ]; then # id -n -u 用户名 id -n -g 基本组组名 echo "Yiyang." else echo "Bu Yiyang." fi |
[root@nono ~]# groupadd hello
[root@nono ~]# useradd -g hello hi #添加用户测试
[root@nono ~]# ./usertest.sh hi
Bu Yiyang.
练习 : (字符测试) 传递一个参数(单字符就行)给脚本,如参数为q,Q,quit,Quit就退出脚本; 否则,就显示用户的参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #!/bin/bash if [ $ # -lt 1 ]; then echo "No such user" exit 4 fi if [ $1 == q ]; then echo "Bye." exit 1 elif [ $1 == Q ]; then echo "Bye Bye." exit 2 elif [ $1 == quit ]; then echo "Bye Bye Bye." exit 3 elif [ $1 == Quit ]; then echo "Bye Bye Bye Bye." exit 4 else echo $1 fi 本文转自 mlwzby 51CTO博客,原文链接:http://blog.51cto.com/aby028/1826195 |
转载地址:http://ezpdx.baihongyu.com/