如何设定变量,引用
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 |