转载:http://blog.csdn.net/zjf280441589/article/details/39667929
简单的示例Shell程序
示例1.
- #!/bin/bash
- #This is to show what a shell script looks like
- echo "Our first example"
- echo # This inserts an empty line in output.
- echo "We are currently in the following directory."
- /bin/pwd
- echo
- echo "This directory contains the following files"
- /bin/ls -l .
示例2.
- #!/bin/bash
- # Auto mail for system info
-
- /bin/date +%F >> /tmp/sysinfo
- echo >> /tmp/sysinfo
-
- echo "Disk info:" >> /tmp/sysinfo
- /bin/df -h >> /tmp/sysinfo
- echo >> /tmp/sysinfo
-
- echo "Online users:" >> /tmp/sysinfo
- /usr/bin/who | /bin/grep -v root >> /tmp/sysinfo
- echo >> /tmp/sysinfo
-
- echo "Memory info:" >> /tmp/sysinfo
- /usr/bin/free -m >> /tmp/sysinfo
- echo >> /tmp/sysinfo
-
- # Write to root
- /usr/bin/write root < /tmp/sysinfo && /bin/rm -f /tmp/sysinfo
-
- # crontab -e
- # 0 9 * * 1-5 ./sysinfo.sh
Shell结构
1、#!指定执行脚本的Shell
2、#注释行,描述该脚本的作用,负责人等信息
3、命令和控制结构
创建shell程序的步骤
第一步:创建一个包含命令和控制结构的文件。
第二步:修改这个文件的权限使它可以执行: chmod u+x
第三步:执行 ./example 或 sh example 或 . sysinfo.sh
Shell变量
变量:是shell传递数据的一种方法,用来代表每个取值的符号名。
Shell有两类变量:临时变量和永久变量。
临时变量是shell程序内部定义的,其使用范围仅限于定义它的程序,对其它程序不可见。包括:用户自定义变量、位置变量。
永久变量是环境变量,其值不随shell脚本的执行结束而消失。
1、用户自定义变量
用户定义的变量由字母或下划线开头,由字母、数字或下划线序列组成,区分大小写。变量名长度没有限制。在使用变量值时,要在变量名前加上前缀“$”。
2、设置和使用变量
设置变量:习惯上用大写字母来命名变量。变量名只能以字母表中的字符开头,不能用数字。
变量赋值:“=”两边没有空格。
定义时赋值,如NUM=1
将一个命令的执行结果赋给变量,如:TIME=`date`;TIME=$(date +%F)
将一个变量的值赋给另一个变量,如:B=120 ; A =$B
使用echo命令查看变量值。例如:echo $A
3、包含多个字的变量:
NAME=Mike Ron #运行时出错,应改为:
NAME=“Mike Ron” 或 $NAME=‘Mike Ron’
4、单引号与双引号的区别
比如:定义DATE=$(date +%F)
time=”time is $DATE”
echo $time
time='time is $DATE'
echo $time
单引号之间的内容原封不动地指定给了变量。
5、 set查看系统中定义的所有变量
unset删除所定义的变量
6、位置变量
Shell解释执行用户命令时,将命令行的第一个部分作为命令名,其它部分作为参数。由出现在命令行上的位置确定的参数称为位置参数。
例如:
ls -l file1 file2 file3
$0 这个程序的文件名 ls -l
$n 这个程序的第n个参数值,n=1~9
7、特殊变量
$* 这个程序的所有参数
$# 这个程序的参数个数
$$ 这个程序的PID
$! 执行上一个后台命令的PID
$? 执行上一个命令的返回值
示例-autobak.sh
- #!/bin/bash
- # backup files by date
-
- DATE=$(/bin/date +%Y%m%d)
- /bin/tar -cf /backup/$1.$DATE.tar $1 > /dev/null 2>> /backup/$1.bak.log
- /bin/gzip /backup/$1.$DATE.tar
-
- if [ $? -eq 0 ]
- then
- echo "$1 $DATE backup successfully" >> /backup/$1.bak.log
- else
- echo "ERROR: failure $1 $DATE backup" >> /bakup/$1.bak.log
- fi
-
- # crontable -e
- # 0 3 * * 2,5 script
示例-special.sh
- #!/bin/bash
- # A test script for special var
-
- echo '$# is' $#
- echo '$* is' $*
- echo '$0 is' $0
- echo '$? is' $?
- echo '$$ is' $$
- echo '$2 is' $2
Shell命令
1、read命令[交互方式]
read USERNAME
示例-read.sh
- #!/bin/bash
- # A test script for read
-
- read first second third
-
- echo "Your first parameter is $first"
- echo "Your second parameter is $second"
- echo "Your third parameter is $third"
#sh -x 命令:单步调试显示执行
2、expr命令,对整型变量进行运算
如: expr 3 + 5 #”+”号之间须有空格
expr $var1 - 5
expr $var1 / $var2
expr $var3 \* 10 #”*”号需要转义符”\”
复杂的运算:
expr `expr 5 + 7`/$var4
将运算结果赋予变量:
var4=` expr $var1 / $var2 `
示例-expr.sh
- #!/bin/bash
- # A test for expr
-
- a=10
- b=20
- c=30
-
- val1=$(expr $a + $b + $c)
- echo "The value of val1 is $val1"
- val2=$(expr $c / $b)
- echo "The value of val2 is $val2"
- val3=`expr $a \* $b`
- echo "The value of val3 is $val3"
- val4=`expr $a + $c / $b`
- echo 'The value of $a + $c / $b is ' $val4
变量测试语句-test
作用:用来测试变量是否相等,是否为空,文件类型等。
格式:
test 测试条件 或 [] #范围:整数,字符串,文件
1)整数测试:
test int1 -eq int2 测试整数是否相等
test int1 -ge int2 测试int1是否>=int2
test int1 -gt int2 测试int1是否>int2
test int1 -le int2 测试int1是否<=int2
test int1 -lt int2 测试int1是否<int2
test int1 -ne int2 测试整数是否不相等
2)字符串测试:
test str1=str2 测试字符串是否相等
test str1!=str2 测试字符串是否不相等
test str1 测试字符串是否不为空
test -n str1 测试字符串是否不为空
test -z str1 测试字符串是否为空
3)文件测试:
test -d file 指定文件是否目录
test -f file 指定文件是否常规文件
test -x file 指定文件是否可执行
test -r file 指定文件是否可读
test -w file 指定文件是否可写
test -a file 指定文件是否存在
test -s file 文件的大小是否非0
注:test测试语句一般不单独使用,一般作为if语句的测试条件,如;
- if test -d file
- then
- ....
- fi
test的变量的简写形式”[]”
示例-apachtest.sh
- #!/bin/bash
- # A test shell script for test Apache is running or not
-
- web=$(/usr/bin/pgrep httpd)
-
- echo "Now let's test the Apache..."
- echo
-
- #if [ "$web" != "" ]
- if [ -n "$web" ]
- then
- echo "Apache is running..."
- else
- echo "Apache is NOT running..."
- /etc/rc.d/init.d/httpd start
- fi
流程控制语句
流控制语句:用于控制shell程序的流程
exit语句:退出程序执行,并返回一个返回码,返回码为0表示正常退出,非0表示非正常退出。
例如:exit 0
一、if
if/then格式
- if test -d $1
- then
- ...
- fi
示例-if_then.sh
- #!/bin/bash
- # A test shell script for if/then
-
- if [ -x /etc/rc.d/init.d/httpd ]
- then
- echo "Script: /etc/rc.d/init.d/httdp have x power!"
- /etc/rc.d/init.d/httpd restart
- fi
if/else格式
- if 条件1
- then
- 命令1
- elif 条件2
- then
- 命令2
- else
- 命令3
- fi
多个条件的联合:
-a: 逻辑与,仅当两个条件都成立时,结果为真。
-o: 逻辑或,两个条件只要有一个成立,结果为真。
示例-if_else.sh
- #!/bin/bash
- # A test shell script for if/elif/else
-
- echo -n "Please input a filename: "
- read filename
-
- if [ -d $filename ]
- then
- echo "$filename is a directory"
- elif [ -f $filename ]
- then
- echo "$filename is a commen file"
- elif [ -c $filename -o -b $filename ]
- then
- echo "$filename is a device file"
- else
- echo "$filename is a unkown file"
- fi
示例-if_elif_exit.sh
- #!/bin/bash
- # A test shell script for if/elif
-
- if [ $# -ne 2 ]
- then
- echo "Not enough parameters"
- exit 1
- fi
-
- if [ $1 -gt $2 ]
- then
- echo "$1 is great then $2"
- elif [ $1 -lt $2 ]
- then
- echo "$1 is little then $2"
- else
- echo "$1 is equal as $2"
- fi
二、for/in
- for 变量 in 名字表
- do
- 命令列表
- done
示例-for.sh
- #!/bin/bash
- # A test shell script for "for"
-
- for DAY in Sunday Monday Tuesday Wednesday Thursday Friday Saturday
- do
- echo "The day is $DAY"
- done
awk命令[分段提取]
awk -F域分隔符 ‘命令’[单引号] #如果不用-F指定分割符,默认为空格
1、检测系统中UID为0的用户
awk -F: '$3==0 {print $1}' /etc/passwd
#awk -F: '{print $1}' /etc/passwd
-F: 指定分割附为:
$3 表示以:为分割附的第三位
2、检测系统中密码为空的用户
awk -F: 'length($2)==0 {print $1}' /etc/shadow
#ps aux | grep -v root | awk '{print $2}'
示例-awk.sh
- #!/bin/bash
- # A test script for desplay users infomation
-
- /bin/echo -n "Please input a username: "
- read username
-
- /bin/grep $username /etc/passwd > /dev/null 2> /dev/null
-
- if [ $? -eq 0 ]
- then
- /bin/echo "username is: $username"
- else
- /bin/echo "user: $username is not exits."
- exit 1
- fi
- /bin/echo
-
- # list /etc/passwd info
- userinfo=`/bin/grep ^$username:x /etc/passwd`
- uid=`echo $userinfo | awk -F: '{print $3}'`
- gid=`echo $userinfo | awk -F: '{print $4'}`
- dir=`echo $userinfo | awk -F: '{print $6}'`
- shell=`echo $userinfo | awk -F: '{print $7}'`
-
- # get /etc/group info
- groupinfo=`/bin/grep x:$gid /etc/group`
- gname=`/bin/echo $groupinfo | awk -F: '{print $1}'`
-
- /bin/echo "user id is: $uid"
- /bin/echo "default group is: $gname"
- /bin/echo "home directory is: $dir"
- /bin/echo "shell is: $shell"
- /bin/echo "group member info:"
-
- # get group members
- groups=`/usr/bin/groups $username`
- /bin/echo $groups
- /bin/echo
-
- # get online info
- online=`/usr/bin/who | grep $username`
- if [ -z "$online" ]
- then
- echo "$username is not online"
- else
- echo "$username is online..."
- fi
实例-killuser.sh
- #思路:将一个用户所有的进程包括shell都关闭,则相当于将该用户踢出了系统
- #!/bin/bash
- # A shell sript to kill a user in Linux
-
- username=$1
-
- killpid=`/bin/ps aux | grep $username | awk '{print $2}'`
-
- for PID in $killpid
- do
- /bin/kill -9 $PID 2> /dev/null
- done
流程控制语句
三、select/in[较少用]
格式:
- select [变量] in [关键字]
- do
- command 1
- ... ...
- command n
- done
- #select把关键字中的每一项做成类似表单,以交互的方式执行do和done之间的命令
示例-select.sh
- #!/bin/bash
- # Show select usage
-
- echo "What's your favorate OS?"
-
- select var in "Linux" "Windows" "UNIX" "Other"
- do
- break
- done
-
- echo "You have selected $var"
四、case/esac
格式:
- case 变量 in
- 字符串1)
- 命令列表1
- ;;
- ...
- 字符串n)
- 命令列表n
- ;;
- esac
示例-case.sh
- #!/bin/bash
- # Show Usage for case/esac
-
- echo "*********************************"
- echo "Please select a oprator as below:"
- echo "C ... copy"
- echo "D ... delete"
- echo "B ... backup"
- echo "*********************************"
-
- read op
- case $op in
- C)
- echo "copy...."
- ;;
- D)
- echo "delete...."
- ;;
- B)
- echo "backup..."
- ;;
- *)
- echo "Unknow operator!"
- exit 1
- esac
示例-select.case
- #!/bin/bash
- # A test shell script for select and case
-
- echo "a is 5, b is 3, please select your method"
- a=5
- b=3;
-
- select var in "a+b" "a-b" "a*b" "a/b"
- do
- break
- done
-
- case $var in
- "a+b")
- echo "a+b="`expr $a + $b `
- ;;
- "a-b")
- echo "a-b="`expr $a - $b`
- ;;
- "a*b")
- echo "a*b="`expr $a \* $b`
- ;;
- "a/b")
- echo "a/b="`expr $a / $b`
- ;;
- *)
- echo "input error..."
- exit 1
- esac
实例-/etc/rc.d/init.d/httpd部分源代码
- # See how we were called.
- case "$1" in
- start)
- start
- ;;
- stop)
- stop
- ;;
- status)
- ;;
- restart)
- stop
- start
- ;;
- condrestart|try-restart)
- if status -p ${pidfile} $httpd >&/dev/null; then
- stop
- start
- fi
- ;;
- force-reload|reload)
- reload
- ;;
- graceful|help|configtest|fullstatus)
- $apachectl $@
- RETVAL=$?
- ;;
- *)
- echo $"Usage: $prog {start|stop|restart|condrestart|try-restart|force-reload|reload|status|fullstatus|graceful|help|configtest}"
- RETVAL=2
- esac
五、while
格式:
- while 条件 #无限:while true
- do
- 命令
- done
示例-while.sh
- #!/bin/bash
- # A usage for while
-
- num=1
- while [ $num -le 10 ]
- do
- echo $(expr $num \* $num)
- let num++
- done
示例-useradd.sh
- #!/bin/bash
- # A shell script to add user(s)
- #echo 123456 | passwd --stdin xiaofang #用非交互方式设置xiaofang的密码
-
- echo -n "Plese input the user name: "
- read username
- echo -n "Plese input the sum users: "
- read sum
-
- num=1
- while [ $num -le $sum ]
- do
- /usr/sbin/useradd "$username$num"
- if [ $? -ne 0 ]
- then
- echo "user: $username already exists."
- exit 1
- fi
-
- let num++
- done
-
- echo -n "Please input the passwd for this users: "
- read passwd
-
- i=1
- while [ $i -le $sum ]
- do
- echo $passwd | /usr/bin/passwd --stdin "$username$i"
- let i++
- done
示例-userdel.sh
- #!/bin/bash
- # A shell script for delete user(s)
-
- echo -n "Please input the username: "
- read username
- echo -n "Please input the user number: "
- read num
-
- i=1
- while [ $i -le $num ]
- do
- /usr/sbin/userdel -r $username$i
- if [ $? -ne 0 ]
- then
- echo "User: $username$i is not exists."
- let i++
- continue
- fi
-
- let i++
- done
六、until
格式:
- until 条件
- do
- 命令
- done
- #until类似while循环,不同的是until是条件返回值为假时才继续执行。
示例-until.sh
- #!/bin/bash
- # A script to show until usage.
-
- echo "Please input Y/y to stop..."
- read input
-
- until [ "$input" = "Y" ] || [ "$input" = "y" ]
- do
- echo "input error, input again!"
- read input
- done
七、跳出循环:break和continue
break:跳出整个循环
continue:跳过本次循环,进行下次循环
示例-break_continue.sh
- #!/bin/bash
- # A test shell script for break&continue
-
- while true
- do
- echo "*****************************"
- echo "Please have a select as blow:"
- echo "1 Copy"
- echo "2 Delete"
- echo "3 Backup"
- echo "4 Quit***********************"
- read op
-
- case $op in
- "1")
- echo "$op is Copy"
- ;;
- "2")
- echo "$op is Delete"
- ;;
- "3")
- echo "$op is Backup"
- ;;
- "4")
- echo "Exit..."
- break
- ;;
- "*")
- echo "Invalide selectino, please select again..."
- continue
- ;;
- esac
- done
八、shift指令
参数左移,每执行一次,参数序列顺次左移一个位置,$#的值减1, 用于分别处理每个参数,移出去的参数不再可用
示例-shift.sh
- #!/bin/bash
- # A test shell script for shift
-
- if [ $# -lt 1 ]
- then
- echo "No enough parameters"
- exit 1
- fi
-
- num=0
- while [ $# -gt 0 ]
- do
- echo '$1 is '$1
- let num++
- shift
- done
-
- echo $num
函数应用
实例-/etc/rc.d/init.d/httpd中的start源代码
一、函数的定义:
- 函数名 ()
- {
- 命令序列
- }
二、函数的调用:不带()
函数名 参数1 参数2 ... 参数n
实例-调用
三、函数中的变量:
变量均为全局变量,没有局部变量
四、函数中的参数:
调用函数时,可以传递参数,在函数中用$1、$2...来引用
示例-function.sh
- #!/bin/bash
- # A test shell script for function
-
- # function
- Help(){
- echo "Usage: sh function \$1 \$2 \$3"
- }
-
- Display(){
- echo "three argument: $1 $2 $3"
- }
-
- # main
- if [ $# -ne 3 ]
- then
- Help
- else
- echo "Think you for your input"
- Display $1 $2 $3
- fi
Shell 脚本调试
sh -x script 这将执行该脚本并显示所有变量的值。
sh -n script 不执行脚本只是检查语法的模式,将返回所有语法错误。
最佳实践-命令最好使用绝对路径
一个脚本能够执行-
1.对脚本有rx权限,只有r,可以使用sh执行
2.对脚本所在目录至少有rx权限
拓展实例-setuid.sh
- #!/bin/bash
- # After the system installed, please check setuid files first for security
- # mkdir /backup
- # find / -perm -4000 -o -perm -2000 > /backup/setuid.list
-
- /bin/find / -perm -4000 -o -perm -2000 > /tmp/setuid.list 2> /dev/null
-
- for var in `/bin/cat /tmp/setuid.list`
- do
- /bin/grep $var /backup/setuid.list > /dev/null 2> /dev/null
- if [ $? -ne 0 ]
- then
- echo "$var is not in /backup/setuid.list, It's danger!"
- fi
- done
转载:http://blog.csdn.net/zjf280441589/article/details/39667929
简单的示例Shell程序
示例1.
- #!/bin/bash
- #This is to show what a shell script looks like
- echo "Our first example"
- echo # This inserts an empty line in output.
- echo "We are currently in the following directory."
- /bin/pwd
- echo
- echo "This directory contains the following files"
- /bin/ls -l .
示例2.
- #!/bin/bash
- # Auto mail for system info
- /bin/date +%F >> /tmp/sysinfo
- echo >> /tmp/sysinfo
- echo "Disk info:" >> /tmp/sysinfo
- /bin/df -h >> /tmp/sysinfo
- echo >> /tmp/sysinfo
- echo "Online users:" >> /tmp/sysinfo
- /usr/bin/who | /bin/grep -v root >> /tmp/sysinfo
- echo >> /tmp/sysinfo
- echo "Memory info:" >> /tmp/sysinfo
- /usr/bin/free -m >> /tmp/sysinfo
- echo >> /tmp/sysinfo
- # Write to root
- /usr/bin/write root < /tmp/sysinfo && /bin/rm -f /tmp/sysinfo
- # crontab -e
- # 0 9 * * 1-5 ./sysinfo.sh
Shell结构
1、#!指定执行脚本的Shell
2、#注释行,描述该脚本的作用,负责人等信息
3、命令和控制结构
创建shell程序的步骤
第一步:创建一个包含命令和控制结构的文件。
第二步:修改这个文件的权限使它可以执行: chmod u+x
第三步:执行 ./example 或 sh example 或 . sysinfo.sh
Shell变量
变量:是shell传递数据的一种方法,用来代表每个取值的符号名。
Shell有两类变量:临时变量和永久变量。
临时变量是shell程序内部定义的,其使用范围仅限于定义它的程序,对其它程序不可见。包括:用户自定义变量、位置变量。
永久变量是环境变量,其值不随shell脚本的执行结束而消失。
1、用户自定义变量
用户定义的变量由字母或下划线开头,由字母、数字或下划线序列组成,区分大小写。变量名长度没有限制。在使用变量值时,要在变量名前加上前缀“$”。
2、设置和使用变量
设置变量:习惯上用大写字母来命名变量。变量名只能以字母表中的字符开头,不能用数字。
变量赋值:“=”两边没有空格。
定义时赋值,如NUM=1
将一个命令的执行结果赋给变量,如:TIME=`date`;TIME=$(date +%F)
将一个变量的值赋给另一个变量,如:B=120 ; A =$B
使用echo命令查看变量值。例如:echo $A
3、包含多个字的变量:
NAME=Mike Ron #运行时出错,应改为:
NAME=“Mike Ron” 或 $NAME=‘Mike Ron’
4、单引号与双引号的区别
比如:定义DATE=$(date +%F)
time=”time is $DATE”
echo $time
time='time is $DATE'
echo $time
单引号之间的内容原封不动地指定给了变量。
5、 set查看系统中定义的所有变量
unset删除所定义的变量
6、位置变量
Shell解释执行用户命令时,将命令行的第一个部分作为命令名,其它部分作为参数。由出现在命令行上的位置确定的参数称为位置参数。
例如:
ls -l file1 file2 file3
$0 这个程序的文件名 ls -l
$n 这个程序的第n个参数值,n=1~9
7、特殊变量
$* 这个程序的所有参数
$# 这个程序的参数个数
$$ 这个程序的PID
$! 执行上一个后台命令的PID
$? 执行上一个命令的返回值
示例-autobak.sh
- #!/bin/bash
- # backup files by date
- DATE=$(/bin/date +%Y%m%d)
- /bin/tar -cf /backup/$1.$DATE.tar $1 > /dev/null 2>> /backup/$1.bak.log
- /bin/gzip /backup/$1.$DATE.tar
- if [ $? -eq 0 ]
- then
- echo "$1 $DATE backup successfully" >> /backup/$1.bak.log
- else
- echo "ERROR: failure $1 $DATE backup" >> /bakup/$1.bak.log
- fi
- # crontable -e
- # 0 3 * * 2,5 script
示例-special.sh
- #!/bin/bash
- # A test script for special var
- echo '$# is' $#
- echo '$* is' $*
- echo '$0 is' $0
- echo '$? is' $?
- echo '$$ is' $$
- echo '$2 is' $2
Shell命令
1、read命令[交互方式]
read USERNAME
示例-read.sh
- #!/bin/bash
- # A test script for read
- read first second third
- echo "Your first parameter is $first"
- echo "Your second parameter is $second"
- echo "Your third parameter is $third"
#sh -x 命令:单步调试显示执行
2、expr命令,对整型变量进行运算
如: expr 3 + 5 #”+”号之间须有空格
expr $var1 - 5
expr $var1 / $var2
expr $var3 \* 10 #”*”号需要转义符”\”
复杂的运算:
expr `expr 5 + 7`/$var4
将运算结果赋予变量:
var4=` expr $var1 / $var2 `
示例-expr.sh
- #!/bin/bash
- # A test for expr
- a=10
- b=20
- c=30
- val1=$(expr $a + $b + $c)
- echo "The value of val1 is $val1"
- val2=$(expr $c / $b)
- echo "The value of val2 is $val2"
- val3=`expr $a \* $b`
- echo "The value of val3 is $val3"
- val4=`expr $a + $c / $b`
- echo 'The value of $a + $c / $b is ' $val4
变量测试语句-test
作用:用来测试变量是否相等,是否为空,文件类型等。
格式:
test 测试条件 或 [] #范围:整数,字符串,文件
1)整数测试:
test int1 -eq int2 测试整数是否相等
test int1 -ge int2 测试int1是否>=int2
test int1 -gt int2 测试int1是否>int2
test int1 -le int2 测试int1是否<=int2
test int1 -lt int2 测试int1是否<int2
test int1 -ne int2 测试整数是否不相等
2)字符串测试:
test str1=str2 测试字符串是否相等
test str1!=str2 测试字符串是否不相等
test str1 测试字符串是否不为空
test -n str1 测试字符串是否不为空
test -z str1 测试字符串是否为空
3)文件测试:
test -d file 指定文件是否目录
test -f file 指定文件是否常规文件
test -x file 指定文件是否可执行
test -r file 指定文件是否可读
test -w file 指定文件是否可写
test -a file 指定文件是否存在
test -s file 文件的大小是否非0
注:test测试语句一般不单独使用,一般作为if语句的测试条件,如;
- if test -d file
- then
- ....
- fi
test的变量的简写形式”[]”
示例-apachtest.sh
- #!/bin/bash
- # A test shell script for test Apache is running or not
- web=$(/usr/bin/pgrep httpd)
- echo "Now let's test the Apache..."
- echo
- #if [ "$web" != "" ]
- if [ -n "$web" ]
- then
- echo "Apache is running..."
- else
- echo "Apache is NOT running..."
- /etc/rc.d/init.d/httpd start
- fi
流程控制语句
流控制语句:用于控制shell程序的流程
exit语句:退出程序执行,并返回一个返回码,返回码为0表示正常退出,非0表示非正常退出。
例如:exit 0
一、if
if/then格式
- if test -d $1
- then
- ...
- fi
示例-if_then.sh
- #!/bin/bash
- # A test shell script for if/then
- if [ -x /etc/rc.d/init.d/httpd ]
- then
- echo "Script: /etc/rc.d/init.d/httdp have x power!"
- /etc/rc.d/init.d/httpd restart
- fi
if/else格式
- if 条件1
- then
- 命令1
- elif 条件2
- then
- 命令2
- else
- 命令3
- fi
多个条件的联合:
-a: 逻辑与,仅当两个条件都成立时,结果为真。
-o: 逻辑或,两个条件只要有一个成立,结果为真。
示例-if_else.sh
- #!/bin/bash
- # A test shell script for if/elif/else
- echo -n "Please input a filename: "
- read filename
- if [ -d $filename ]
- then
- echo "$filename is a directory"
- elif [ -f $filename ]
- then
- echo "$filename is a commen file"
- elif [ -c $filename -o -b $filename ]
- then
- echo "$filename is a device file"
- else
- echo "$filename is a unkown file"
- fi
示例-if_elif_exit.sh
- #!/bin/bash
- # A test shell script for if/elif
- if [ $# -ne 2 ]
- then
- echo "Not enough parameters"
- exit 1
- fi
- if [ $1 -gt $2 ]
- then
- echo "$1 is great then $2"
- elif [ $1 -lt $2 ]
- then
- echo "$1 is little then $2"
- else
- echo "$1 is equal as $2"
- fi
二、for/in
- for 变量 in 名字表
- do
- 命令列表
- done
示例-for.sh
- #!/bin/bash
- # A test shell script for "for"
- for DAY in Sunday Monday Tuesday Wednesday Thursday Friday Saturday
- do
- echo "The day is $DAY"
- done
awk命令[分段提取]
awk -F域分隔符 ‘命令’[单引号] #如果不用-F指定分割符,默认为空格
1、检测系统中UID为0的用户
awk -F: '$3==0 {print $1}' /etc/passwd
#awk -F: '{print $1}' /etc/passwd
-F: 指定分割附为:
$3 表示以:为分割附的第三位
2、检测系统中密码为空的用户
awk -F: 'length($2)==0 {print $1}' /etc/shadow
#ps aux | grep -v root | awk '{print $2}'
示例-awk.sh
- #!/bin/bash
- # A test script for desplay users infomation
- /bin/echo -n "Please input a username: "
- read username
- /bin/grep $username /etc/passwd > /dev/null 2> /dev/null
- if [ $? -eq 0 ]
- then
- /bin/echo "username is: $username"
- else
- /bin/echo "user: $username is not exits."
- exit 1
- fi
- /bin/echo
- # list /etc/passwd info
- userinfo=`/bin/grep ^$username:x /etc/passwd`
- uid=`echo $userinfo | awk -F: '{print $3}'`
- gid=`echo $userinfo | awk -F: '{print $4'}`
- dir=`echo $userinfo | awk -F: '{print $6}'`
- shell=`echo $userinfo | awk -F: '{print $7}'`
- # get /etc/group info
- groupinfo=`/bin/grep x:$gid /etc/group`
- gname=`/bin/echo $groupinfo | awk -F: '{print $1}'`
- /bin/echo "user id is: $uid"
- /bin/echo "default group is: $gname"
- /bin/echo "home directory is: $dir"
- /bin/echo "shell is: $shell"
- /bin/echo "group member info:"
- # get group members
- groups=`/usr/bin/groups $username`
- /bin/echo $groups
- /bin/echo
- # get online info
- online=`/usr/bin/who | grep $username`
- if [ -z "$online" ]
- then
- echo "$username is not online"
- else
- echo "$username is online..."
- fi
实例-killuser.sh
- #思路:将一个用户所有的进程包括shell都关闭,则相当于将该用户踢出了系统
- #!/bin/bash
- # A shell sript to kill a user in Linux
- username=$1
- killpid=`/bin/ps aux | grep $username | awk '{print $2}'`
- for PID in $killpid
- do
- /bin/kill -9 $PID 2> /dev/null
- done
流程控制语句
三、select/in[较少用]
格式:
- select [变量] in [关键字]
- do
- command 1
- ... ...
- command n
- done
- #select把关键字中的每一项做成类似表单,以交互的方式执行do和done之间的命令
示例-select.sh
- #!/bin/bash
- # Show select usage
- echo "What's your favorate OS?"
- select var in "Linux" "Windows" "UNIX" "Other"
- do
- break
- done
- echo "You have selected $var"
四、case/esac
格式:
- case 变量 in
- 字符串1)
- 命令列表1
- ;;
- ...
- 字符串n)
- 命令列表n
- ;;
- esac
示例-case.sh
- #!/bin/bash
- # Show Usage for case/esac
- echo "*********************************"
- echo "Please select a oprator as below:"
- echo "C ... copy"
- echo "D ... delete"
- echo "B ... backup"
- echo "*********************************"
- read op
- case $op in
- C)
- echo "copy...."
- ;;
- D)
- echo "delete...."
- ;;
- B)
- echo "backup..."
- ;;
- *)
- echo "Unknow operator!"
- exit 1
- esac
示例-select.case
- #!/bin/bash
- # A test shell script for select and case
- echo "a is 5, b is 3, please select your method"
- a=5
- b=3;
- select var in "a+b" "a-b" "a*b" "a/b"
- do
- break
- done
- case $var in
- "a+b")
- echo "a+b="`expr $a + $b `
- ;;
- "a-b")
- echo "a-b="`expr $a - $b`
- ;;
- "a*b")
- echo "a*b="`expr $a \* $b`
- ;;
- "a/b")
- echo "a/b="`expr $a / $b`
- ;;
- *)
- echo "input error..."
- exit 1
- esac
实例-/etc/rc.d/init.d/httpd部分源代码
- # See how we were called.
- case "$1" in
- start)
- start
- ;;
- stop)
- stop
- ;;
- status)
- ;;
- restart)
- stop
- start
- ;;
- condrestart|try-restart)
- if status -p ${pidfile} $httpd >&/dev/null; then
- stop
- start
- fi
- ;;
- force-reload|reload)
- reload
- ;;
- graceful|help|configtest|fullstatus)
- $apachectl $@
- RETVAL=$?
- ;;
- *)
- echo $"Usage: $prog {start|stop|restart|condrestart|try-restart|force-reload|reload|status|fullstatus|graceful|help|configtest}"
- RETVAL=2
- esac
五、while
格式:
- while 条件 #无限:while true
- do
- 命令
- done
示例-while.sh
- #!/bin/bash
- # A usage for while
- num=1
- while [ $num -le 10 ]
- do
- echo $(expr $num \* $num)
- let num++
- done
示例-useradd.sh
- #!/bin/bash
- # A shell script to add user(s)
- #echo 123456 | passwd --stdin xiaofang #用非交互方式设置xiaofang的密码
- echo -n "Plese input the user name: "
- read username
- echo -n "Plese input the sum users: "
- read sum
- num=1
- while [ $num -le $sum ]
- do
- /usr/sbin/useradd "$username$num"
- if [ $? -ne 0 ]
- then
- echo "user: $username already exists."
- exit 1
- fi
- let num++
- done
- echo -n "Please input the passwd for this users: "
- read passwd
- i=1
- while [ $i -le $sum ]
- do
- echo $passwd | /usr/bin/passwd --stdin "$username$i"
- let i++
- done
示例-userdel.sh
- #!/bin/bash
- # A shell script for delete user(s)
- echo -n "Please input the username: "
- read username
- echo -n "Please input the user number: "
- read num
- i=1
- while [ $i -le $num ]
- do
- /usr/sbin/userdel -r $username$i
- if [ $? -ne 0 ]
- then
- echo "User: $username$i is not exists."
- let i++
- continue
- fi
- let i++
- done
六、until
格式:
- until 条件
- do
- 命令
- done
- #until类似while循环,不同的是until是条件返回值为假时才继续执行。
示例-until.sh
- #!/bin/bash
- # A script to show until usage.
- echo "Please input Y/y to stop..."
- read input
- until [ "$input" = "Y" ] || [ "$input" = "y" ]
- do
- echo "input error, input again!"
- read input
- done
七、跳出循环:break和continue
break:跳出整个循环
continue:跳过本次循环,进行下次循环
示例-break_continue.sh
- #!/bin/bash
- # A test shell script for break&continue
- while true
- do
- echo "*****************************"
- echo "Please have a select as blow:"
- echo "1 Copy"
- echo "2 Delete"
- echo "3 Backup"
- echo "4 Quit***********************"
- read op
- case $op in
- "1")
- echo "$op is Copy"
- ;;
- "2")
- echo "$op is Delete"
- ;;
- "3")
- echo "$op is Backup"
- ;;
- "4")
- echo "Exit..."
- break
- ;;
- "*")
- echo "Invalide selectino, please select again..."
- continue
- ;;
- esac
- done
八、shift指令
参数左移,每执行一次,参数序列顺次左移一个位置,$#的值减1, 用于分别处理每个参数,移出去的参数不再可用
示例-shift.sh
- #!/bin/bash
- # A test shell script for shift
- if [ $# -lt 1 ]
- then
- echo "No enough parameters"
- exit 1
- fi
- num=0
- while [ $# -gt 0 ]
- do
- echo '$1 is '$1
- let num++
- shift
- done
- echo $num
函数应用
实例-/etc/rc.d/init.d/httpd中的start源代码
一、函数的定义:
- 函数名 ()
- {
- 命令序列
- }
二、函数的调用:不带()
函数名 参数1 参数2 ... 参数n
实例-调用
三、函数中的变量:
变量均为全局变量,没有局部变量
四、函数中的参数:
调用函数时,可以传递参数,在函数中用$1、$2...来引用
示例-function.sh
- #!/bin/bash
- # A test shell script for function
- # function
- Help(){
- echo "Usage: sh function \$1 \$2 \$3"
- }
- Display(){
- echo "three argument: $1 $2 $3"
- }
- # main
- if [ $# -ne 3 ]
- then
- Help
- else
- echo "Think you for your input"
- Display $1 $2 $3
- fi
Shell 脚本调试
sh -x script 这将执行该脚本并显示所有变量的值。
sh -n script 不执行脚本只是检查语法的模式,将返回所有语法错误。
最佳实践-命令最好使用绝对路径
一个脚本能够执行-
1.对脚本有rx权限,只有r,可以使用sh执行
2.对脚本所在目录至少有rx权限
拓展实例-setuid.sh
- #!/bin/bash
- # After the system installed, please check setuid files first for security
- # mkdir /backup
- # find / -perm -4000 -o -perm -2000 > /backup/setuid.list
- /bin/find / -perm -4000 -o -perm -2000 > /tmp/setuid.list 2> /dev/null
- for var in `/bin/cat /tmp/setuid.list`
- do
- /bin/grep $var /backup/setuid.list > /dev/null 2> /dev/null
- if [ $? -ne 0 ]
- then
- echo "$var is not in /backup/setuid.list, It's danger!"
- fi
- done