Shell Script 学习笔记
1、什么是Shell Script
shell是命令行界面下让我们与操作系统沟通的一个工具接口,script是就是‘"脚本"的意思。
shell script是利用shell的功能所写的一个"程序",这个"程序"是使用纯文本文件,将一些shell的语法与命令(含外部命令)写在文件中,搭配正则表达式、管道命令与数据流重定向等功能,以达到我们想要的处理目的。
shell script可以被简单的看成批处理文件,也可以当做一种程序语言,由于是利用shell的相关工具命令,所以不需要编译即可执行。
1.1、为什么学shell script
1.2、编写并执行第一个shell script
[root@localhost ~]# mkdir scripts
[root@localhost ~]# cd scripts
[root@localhost scripts]# vi sh01.sh
#!/bin/bash
# It's my first script
PATH=/bin:/sbin:/usr/sbin:/usr/local/bin:/usr.local/sbin:~/bin
export PATH
echo -e "hello world \a \n"
exit 0
~
①首先,创建~/scripts目录,编写sh01.sh
②脚本的第一行 #!/bin/bash 声明了这个script使用的shell名称
我们使用的是bash,所以以"#!/bin/bash"来声明这个文件的内容使用的是bash的语法,当脚本被执行时,他能够自动加载bash的相关环境配置文件(一般来说就是non-login shell 的~/.bashrc),并用bash来执行这个脚本
③第二行的#是对script内容的注释
④第三行及第四行是主要环境变量的声明,PATH与LANG一般是最重要的
⑤第五行为程序的主要内容
⑥第六行是返回的执行结果,执行脚本结束后可以输入scho $?可以得到0的值
[root@localhost scripts]# sh sh01.sh
hello world
①直接命令执行:shell.sh文件必须要具备可读与可执行(rx)的权限
[root@localhost scripts]# ls -l
total 4
-rw-r--r--. 1 root root 166 Nov 4 18:16 sh01.sh
[root@localhost scripts]# chmod 755 sh01.sh
[root@localhost scripts]# ls -l
total 4
-rwxr-xr-x. 1 root root 166 Nov 4 18:16 sh01.sh
绝对路径:使用 /root/scripts/sh01.sh 来执行
[root@localhost scripts]# /root/scripts/sh01.sh
hello world
相对路径:当前目录为/root/scripts/时,使用 ./sh01.sh执行
[root@localhost scripts]# ./sh01.sh
hello world
变量PATH功能,将sh01.sh放在PATH指定目录内,例如:~/bin/ 中
②以bash进程来执行:
[root@localhost scripts]# bash sh01.sh
hello world
[root@localhost scripts]# sh sh01.sh
hello world
2、简单的shell scripts练习
2.1、简单范例
①交互式脚本:变量内容由用户决定
[root@localhost scripts]# vi sh02.sh
[root@localhost scripts]# ls
sh01.sh sh02.sh
[root@localhost scripts]# chmod 755 sh02.sh
[root@localhost scripts]# ls
sh01.sh sh02.sh
#!/bin/bash
# Program:
# User input first name and last name.Program shows his full name
# History:
# 2016-11-04 ... ...
PATH=/bin:/sbin:/usr/sbin:/usr/local/bin:/usr.local/sbin:~/bin
export PATH
read -p "Input your first name:" firstname
read -p "Input your last name:" lastname
echo -e "\nYour full name is : $firstname $lastname"
~
[root@localhost scripts]# ./sh02.sh
Input your first name:张
Input your last name:三
Your full name is : 张 三
②随日期变化:利用日期进行文件的创建
[root@localhost scripts]# vi sh03.sh
[root@localhost scripts]# ls
sh01.sh sh02.sh sh03.sh
[root@localhost scripts]# chmod 755 sh03.sh
[root@localhost scripts]#
[root@localhost scripts]# vi sh03.sh
#!/bin/bash
# Program:
# Program creat three file ,which named by user'input
# History:
# 2016-11-04 ... ...
PATH=/bin:/sbin:/usr/sbin:/usr/local/bin:/usr.local/sbin:~/bin
export PATH
# 1.让用户输入文件名,取得fileuser变量
echo -e "I will use ‘touch’ command to creat 3 files."
read -p "Input your filename: " fileuser
# 2.为了避免用户随意按[enter],利用变量功能分析文件名是否已存在
filename=${fileuser:-"filename"} #判断是否有配置文件名
# 3.使用date命令取得所需的日期作为文件名的一部分
date1=$(date --date='2 days ago' +%Y%m%d) #前两天的日期
date2=$(date --date='1 days ago' +%Y%m%d) #前一天的日期
date3=$(date +%Y%m%d) #今天的日期
# 4.下面三行配置文件名
file1=${filename}${date1}
file2=${filename}${date2}
file3=${filename}${date3}
# 5.创建文件
touch "$file1"
touch "$file2"
touch "$file3"
[root@localhost scripts]# ./sh03.sh
I will use ‘touch’ command to creat 3 files.
Input your filename: my
[root@localhost scripts]# ls
my20161102 my20161103 my20161104 sh01.sh sh02.sh sh03.sh
[root@localhost scripts]#
③数值运算:简单的加减乘除
[root@localhost scripts]# vi sh04.sh
#!/bin/bash # Program:
# user input two integer numbers ,program will cross these two numbers # History:
# 2016-11-04 ... ...
PATH=/bin:/sbin:/usr/sbin:/usr/local/bin:/usr.local/sbin:~/bin
export PATH
echo -e "you should input 2 numbers,and i will cross them \n"
read -p "first number: " num1
read -p "second number: " num2
total=$(($num1*$num2))
echo -e "\nThe result of $num1 X $num2 is ==> $total"
[root@localhost scripts]# chmod 755 sh04.sh
[root@localhost scripts]# ./sh04.sh
you should input 2 numbers,and i will cross them
first number: 6
second number: 7
The result of 6 X 7 is ==> 42
2.2、script的执行方式的区别(source,shscript,./script)
①利用直接执行的方式来执行script
[root@localhost scripts]# echo $firstname $lastname
[root@localhost scripts]# ./sh02.sh
Input your first name:张
Input your last name:三
Your full name is : 张 三
[root@localhost scripts]# echo $firstname $lastname
[root@localhost scripts]#
上面的firstname和lastname两个变量并不存在
②利用source来执行脚本,会在父进程中执行
[root@localhost scripts]# source sh02.sh
Input your first name:张
Input your last name:三
Your full name is : 张 三
[root@localhost scripts]# echo $firstname $lastname
张 三
[root@localhost scripts]#
firstname和lastname两个变量存在当前bash中
3、善用判断式
3.1、利用test命令的测试功能
当要检测系统上面某些文件或者相关属性是,利用test命令
举个栗子,现在检查/abc是否存在时:[root@localhost scripts]# test -e /abc
[root@localhost scripts]#
执行结果没有显示任何信息
[root@localhost scripts]# test -e /abc && "exist" || echo "not exist"
not exist
[root@localhost scripts]#
文章末尾粘贴了来自《鸟哥的linux私房菜》的一张表test相关命令的参数,以供参考
现在我们利用test写个简单例子:
[root@localhost scripts]# vi sh05.sh
#!/bin/bash
# Program:
# user input a filename ,program will check the flowing
# 1)exist? 2)file/directory? 3)file permissions
# History:
# 2016-11-04 ... ...
PATH=/bin:/sbin:/usr/sbin:/usr/local/bin:/usr.local/sbin:~/bin
export PATH
# 1)
read -p "input a filename,i will check it :" filename
test -z $filename && echo "You must input a filename" && exit 0
# 2)
test ! -e $filename && echo "The filename '$filename' NOT exist" && exit 0
# 3)
test -f $filename && filetype="regulare file"
test -d $filename && filetype="directory"
test -r $filename && perm="readable"
test -w $filename && perm="$perm writable"
test -x $filename && perm="$perm executable"
# 输出信息
echo "The filename :$filename is a $filetype"
echo "And the permissions are :$perm"
[root@localhost scripts]# chmod 755 sh05.sh
[root@localhost scripts]# ./sh05.sh
input a filename,i will check it :sh01.sh
The filename :sh01.sh is a regulare file
And the permissions are :readable writable executable
[root@localhost scripts]# vi sh05.sh
#!/bin/bash
# Program:
# user input a filename ,program will check the flowing
# 1)exist? 2)file/directory? 3)file permissions
# History:
# 2016-11-04 ... ...
PATH=/bin:/sbin:/usr/sbin:/usr/local/bin:/usr.local/sbin:~/bin
export PATH
# 1)
read -p "input a filename,i will check it :" filename
test -z $filename && echo "You must input a filename" && exit 0
# 2)
test ! -e $filename && echo "The filename '$filename' NOT exist" && exit 0
# 3)
test -f $filename && filetype="regulare file"
test -d $filename && filetype="directory"
test -r $filename && perm="readable"
test -w $filename && perm="$perm writable"
test -x $filename && perm="$perm executable"
# 输出信息
echo "The filename :$filename is a $filetype"
echo "And the permissions are :$perm"
[root@localhost scripts]# chmod 755 sh05.sh
[root@localhost scripts]# ./sh05.sh
input a filename,i will check it :sh01.sh
The filename :sh01.sh is a regulare file
And the permissions are :readable writable executable
3.2、利用判断符号[]
举个栗子:
[root@localhost scripts]# vi sh06.sh
#!/bin/bash
# Program:
# show the user choice
# History:
# 2016-11-04 ... ...
PATH=/bin:/sbin:/usr/sbin:/usr/local/bin:/usr.local/sbin:~/bin
export PATH
read -p "input (Y/N):" yn
[ "$yn" == "Y" -o "$yn" == "y" ] && echo "OK,continue" && exit 0
[ "$yn" == "N" -o "$yn" == "n" ] && echo "Oh,interrupt" && exit 0
echo "I do not konw what your choice is" && exit 0
[root@localhost scripts]# chmod 755 sh06.sh
[root@localhost scripts]# ./sh06.sh
input (Y/N):y
OK,continue
[root@localhost scripts]# ./sh06.sh
input (Y/N):n
Oh,interrupt
3.3、shell script的默认变量($0,$1...)
script针对参数默认设置了一些变量名称
[root@localhost scripts]# vi sh07.sh
#!/bin/bash
# Program:
# show the script name ,parameters...
# History:
# 2016-11-04 ... ...
PATH=/bin:/sbin:/usr/sbin:/usr/local/bin:/usr.local/sbin:~/bin
export PATH
echo "The script name is ==> $0"
echo "Total parameter number is ==> $#"
[ "$#" -lt 2 ] && echo "The number of parameter is less than 2.Stop here" && exit 0
echo "whole parameters is ==> $@"
echo "The 1st parameter is ==> $1"
echo "The 2st parameter is ==> $2"
[root@localhost scripts]# chmod 755 sh07.sh
The script name is ==> ./sh07.sh
Total parameter number is ==> 3
whole parameters is ==> one two three
The 1st parameter is ==> one
The 2st parameter is ==> two
shift:造成参数变量的号码偏移
#!/bin/bash
# Program:
# show the effect of shift function
# History:
# 2016-11-04 ... ...
PATH=/bin:/sbin:/usr/sbin:/usr/local/bin:/usr.local/sbin:~/bin
export PATH
echo "Total parameter number is ==> $#"
echo "whole parameters is ==> $@"
shift #第一次一个变量shift
echo "Total parameter number is ==> $#"
echo "whole parameters is ==> $@"
shift 3 #第二次,三个变量shift
echo "Total parameter number is ==> $#"
echo "whole parameters is ==> $@"
[root@localhost scripts]# chmod 755 sh08.sh
[root@localhost scripts]# ./sh08.sh 1 2 3 4 5 6
Total parameter number is ==> 6
whole parameters is ==> 1 2 3 4 5 6
Total parameter number is ==> 5
whole parameters is ==> 2 3 4 5 6
Total parameter number is ==> 2
whole parameters is ==> 5 6
4、条件判断式
4.1、利用if...then
①单层、简单条件判断式:
if [ 条件判断式 ]; then
#当条件判断式成立时,可进行的命令语句内容
fi #将if反过来写,用来结束if语句
#其中&&代表and || 代表or
可以将sh06.sh改为if...then的样式:
[root@localhost scripts]# cp sh06.sh sh06-2.sh
[root@localhost scripts]# vi sh06-2.sh
#!/bin/bash
# Program:
# show the user choice
# History:
# 2016-11-04 ... ...
PATH=/bin:/sbin:/usr/sbin:/usr/local/bin:/usr.local/sbin:~/bin
export PATH
read -p "input (Y/N):" yn
if [ "$yn" == "Y" ] || [ "$yn" == "y" ]; then
echo "OK,continue"
exit 0
fi
if [ "$yn" == "N" ] || [ "$yn" == "n" ]; then
echo "Oh,interrupt"
exit 0
fi
echo "I do not konw what your choice is" && exit 0
②多重、复杂条件判断式:
多种不同的判断:
# 一个条件判断
if [ 条件判断式 ]; then
#当条件判断成立时,进行的命令内容
else
#当条件判断不成立时,进行的命令内容
fi
更加复杂的情况可以:
# 多个条件判断(if...elif...else)
if [ 条件判断式1 ]; then
#当条件判断1成立时,进行的命令内容
elif [ 条件判断式2 ]; then
#当条件判断2成立时,进行的命令内容
else
#当条件判断全不成立时,进行的命令内容
fi
可以将sh06-2.sh修改成下面这样:
[root@localhost scripts]# cp sh06-2.sh sh06-3.sh
[root@localhost scripts]# vi sh06-3.sh
#!/bin/bash
# Program:
# show the user choice
# History:
# 2016-11-04 ... ...
PATH=/bin:/sbin:/usr/sbin:/usr/local/bin:/usr.local/sbin:~/bin
export PATH
read -p "input (Y/N):" yn
if [ "$yn" == "Y" ] || [ "$yn" == "y" ]; then
echo "OK,continue"
elif [ "$yn" == "N" ] || [ "$yn" == "n" ]; then
echo "Oh,interrupt"
else
echo "I do not konw what your choice is"
fi
exit 0
现在我们想让用户输入"hello"这个关键字时,利用参数的方法可以这样设计:
[root@localhost scripts]# vi sh09.sh
#!/bin/bash
# Program:
# check $1 is equal to "hello"
# History:
# 2016-11-04 ... ...
PATH=/bin:/sbin:/usr/sbin:/usr/local/bin:/usr.local/sbin:~/bin
export PATH
if [ "$1" == "hello" ]; then
echo "Hello,how are you?"
elif [ "$1"=="" ]; then
echo "You must input parameter, ex>{$0 someword}"
else
echo "The parameter is 'hello',ex->{$0 hello}"
fi
[root@localhost scripts]# chmod 755 sh09.sh
[root@localhost scripts]# vi sh09.sh
[root@localhost scripts]# ./sh09.sh
You must input parameter, ex>{./sh09.sh someword}
[root@localhost scripts]#
[root@localhost scripts]# ./sh09.sh hello
Hello,how are you?
netstat命令可以查询到目前主机打开的网络服务端口,可以利用netstat -tuln 获取目前主机有启动的服务:
[root@localhost scripts]# netstat -tuln
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN
tcp 0 0 :::22 :::* LISTEN
tcp 0 0 ::1:631 :::* LISTEN
tcp 0 0 ::1:25 :::* LISTEN
udp 0 0 0.0.0.0:68 0.0.0.0:*
udp 0 0 0.0.0.0:631 0.0.0.0:*
#封包格式 #本地ip:端口 #远程IP:端口 #是否监听
重点关注[本地ip:端口]的那个字段,它代表本机所启动的网络服务,若为127.0.0.1是仅对本机开放,若是0.0.0.0或:::代表对整个Internet开放,几个常见的端口与相关网络服务的关系是:
假设我的主机要检测比较常见的端口21,22,25 及80时
那我如何通过netstat去检查主机是否开机这四个主要的网络服务端口呢?由于每个服务的关键字都在冒号‘:’后面,所以我们可以:
[root@localhost scripts]# vi sh10.sh
#!/bin/bash
# Program:
# Using netstat and grep to detect WWW,SSH,FTP and Mail services.
# History:
# 2016-11-04 ... ...
PATH=/bin:/sbin:/usr/sbin:/usr/local/bin:/usr.local/sbin:~/bin
export PATH
# 1.说明
echo "Now,I will detect your Linux server's services"
echo -e "The WWW,SSH,FTP and Mail will be detect! \n"
# 2.开始测试并输出
testing=$(netstat -tuln | grep ":80") #检测 port 80
if [ "$testing" != "" ]; then
echo "WWW is running in your system."
fi
testing=$(netstat -tuln | grep ":22") #检测 port 22
if [ "$testing" != "" ]; then
echo "SSH is running in your system."
fi
testing=$(netstat -tuln | grep ":21") #检测 port 21
if [ "$testing" != "" ]; then
echo "FTP is running in your system."
fi
testing=$(netstat -tuln | grep ":25") #检测 port 25
if [ "$testing" != "" ]; then
echo "Mail is running in your system."
fi
exit 0
[root@localhost scripts]# chmod 755 sh10.sh
[root@localhost scripts]# ./sh10.sh
Now,I will detect your Linux server's services
The WWW,SSH,FTP and Mail will be detect!
SSH is running in your system.
Mail is running in your system.
4.2、利用case...esac判断
语法:
case $变量名称 in #关键字为case,变量前有$
"第一个变量内容") #每个变量内容用双引号括起来,关键字为小括号
程序段
;; #每个类型结尾使用两个分号处理
"第二个变量内容")
程序段
;;
*) #最后一个变量内容用* 代表所有其他值
exit 1
;;
esac #结束case
修改一下sh09.sh:
#!/bin/bash
# Program:
# check $1 is equal to "hello"
# History:
# 2016-11-04 ... ...
PATH=/bin:/sbin:/usr/sbin:/usr/local/bin:/usr.local/sbin:~/bin
export PATH
case $1 in
"hello")
echo "Hello,how are you?"
;;
"")
echo "You must input parameter, ex>{$0 someword}"
;;
*)
echo "Usage $0 {hello}"
;;
esac
~
[root@localhost scripts]# cp sh09.sh sh09-2.sh
[root@localhost scripts]# vi sh09-2.sh
[root@localhost scripts]# ./sh09-2.sh
You must input parameter, ex>{./sh09-2.sh someword}
[root@localhost scripts]# ./sh09-2.sh hello
Hello,how are you?
一般来说,使用"case $变量 in"这个语法中,"$变量"有两种获取方式:
练习:
</pre><pre name="code" class="plain">#!/bin/bash
# Program:
# this only sccepts the flowing parameters:one,two,three.
# History:
# 2016-11-04 ... ...
PATH=/bin:/sbin:/usr/sbin:/usr/local/bin:/usr.local/sbin:~/bin
export PATH
echo "This program will print your selection !"
case $1 in
"one")
echo "Your choice is one"
;;
"two")
echo "Your choice is two"
;;
"three")
echo "Your choice is three"
;;
*)
echo "Usage $0 {one|two|three}"
;;
esac
[root@localhost scripts]# vi sh12.sh
[root@localhost scripts]# chmod 755 sh12.sh
[root@localhost scripts]# ./sh12.sh one
This program will print your selection !
Your choice is one
4.3、利用function功能
语法:
function fname(){
<span style="white-space:pre"> </span>程序段
}
例子1:
因为shell script 的执行方式是由上而下、由左及右,因此在脚本中的 function 的设置一定要在程序的最前面
我们将sh12.sh改写一下:
[root@localhost scripts]# cp sh12.sh sh12-2.sh
[root@localhost scripts]# vi sh12-2.sh
#!/bin/bash
# Program:
# Use function to repeat information.
# History:
# 2016-11-04 ... ...
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr.local/sbin:~/bin
export PATH
function printit(){
echo -n "Your choice is " #-n参数可以不跳到下一行
}
echo "This program will print your selection !"
case $1 in
"one")
printit; echo $1 | tr 'a-z' 'A-Z' #将参数做大小写转换
;;
"two")
printit; echo $1 | tr 'a-z' 'A-Z' #将参数做大小写转换
;;
"three")
printit; echo $1 | tr 'a-z' 'A-Z' #将参数做大小写转换
;;
*)
echo "Usage $0 {one|two|three}"
;;
esac
[root@localhost scripts]# ./sh12-2.sh two
This program will print your selection !
Your choice is TWO
例子2:
function同样拥有内置变量参数,函数名称表示$0,后续变量也是以$1,$2,$3替代
我们可以在改写一下sh12-2.sh:
[root@localhost scripts]# vi sh12-3.sh
#!/bin/bash
# Program:
# Use function to repeat information.
# History:
# 2016-11-04 ... ...
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr.local/sbin:~/bin
export PATH
function printit(){
echo "Your choice is $1"
}
echo "This program will print your selection !"
case $1 in
"one")
printit 1
;;
"two")
printit 2
;;
"three")
printit 3
;;
*)
echo "Usage $0 {one|two|three}"
;;
esac
[root@localhost scripts]# ./sh12-3.sh one
This program will print your selection !
Your choice is 1
5、循环(loop)
5.1、while do done,util do done(不定循环)
语法:
while [ condition ] <span style="white-space:pre"> </span># 中括号内的为判断式
do <span style="white-space:pre"> </span># do是循环的开始
#程序段
done <span style="white-space:pre"> </span># done循环结束
或者
until [ condition ]
do
#程序段
done
练习1:
假设我要让用户输入yes或者YES才结束程序执行,否则就一直提示用户输入字符串:
[root@localhost scripts]# vi sh13.sh
#!/bin/bash
# Program:
# Repeat question until user input correct answer.
# History:
# 2016-11-04 ... ...
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr.local/sbin:~/bin
export PATH
while [ "$yn" != "yes" -a "$yn" != "YES" ]
do
read -p "input yes/YES to stop this program:" yn
done
acho "OK,you input the correct answer."
exit 0
[root@localhost scripts]# vi sh13.sh
[root@localhost scripts]# chmod 755 sh13.sh
[root@localhost scripts]# ./sh13.sh
input yes/YES to stop this program:no
input yes/YES to stop this program:yes
OK,you input the correct answer.
如果用until则:
[root@localhost scripts]# vi sh13-2.sh
#!/bin/bash
# Program:
# Repeat question until user input correct answer.
# History:
# 2016-11-04 ... ...
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr.local/sbin:~/bin
export PATH
until [ "$yn" == "yes" -o "$yn" == "YES" ]
do
read -p "input yes/YES to stop this program:" yn
done
echo "OK,you input the correct answer."
exit 0
练习2:
计算1+2+3+...+100:
[root@localhost scripts]# vi sh14.sh
#!/bin/bash
# Program:
# use loop to calculate "1+2+3+...+100" result.
# History:
# 2016-11-04 ... ...
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr.local/sbin:~/bin
export PATH
s=0
i=0
while [ "$i" != "100" ]
do
i=$(($i+1)) # 每次i+1
s=$(($s+$i)) # 和的累加
done
echo "the result of " 1+2+3+...+100 " is $s"
exit 0
[root@localhost scripts]# chmod 755 sh14.sh
[root@localhost scripts]# ./sh14.sh
the result of 1+2+3+...+100 is 5050
5.2、for...do...done(固定循环)
语法:
for var in cin1 con2 con3 ...
do
#程序段
done
练习1:
假设我有三只宠物,分别是dog cat elephant,我想每一行都输出"There are dogs"这样的话:
[root@localhost scripts]# vi sh15.sh
#!/bin/bash
# Program:
# using for...loop to print 3 animals
# History:
# 2016-11-04 ... ...
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr.local/sbin:~/bin
export PATH
for animal in "dog" "cat" "elephant"
do
echo "I'm a ${animal}"
done
exit 0
[root@localhost scripts]# ./sh15.sh
I'm a dog
I'm a cat
I'm a elephant
练习2:
由于系统上面各种账号都是写在 /etc/passwd 内的第一个字段,我们可以通过管道命令 cut 找出单纯的账号名称后,以 id 及 finger 分别检查用户的标识符与特殊参数。
由于不同的linux系统上面账号都不一样,此时获取 /etc/passwd 并使用循环处理是一个可行的方案:
#!/bin/bash
# Program:
# use id ,finger command to check system account's information.
# History:
# 2016-11-04 ... ...
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr.local/sbin:~/bin
export PATH
users=$(cut -d ':' -f 1 /etc/passwd) #获取账号名称
for username in $users
do
id $username
finger $username
done
exit 0<span style="font-size:14px;">
</span>
这个操作还可以用在每个账号的删除、更改
练习3:
我要利用ping 这个判断网络状态的命令,来进行网络状态的实时检测时,我要检测的域是本机所在的192.168.1.1~192.168.1.100 由于有100台主机所以:
[root@localhost scripts]# vi sh17.sh
#!/bin/bash
# Program:
# use ping command to check the network's PC state
# History:
# 2016-11-04 ... ...
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr.local/sbin:~/bin
export PATH
network="192.168.1" # 先定义一个域的一部分
for sitenu in $(seq 1 100) # seq为sequence(连续)的缩写
do
# 取得ping 的回传值,正确or失败
ping -c 1 -w 1 ${network}.${sitenu} &> /dev/null && result=0 || result=1
# 开始显示结果是正确的启动(up)还是错误的没有连通(DOWN)
if [ "$result" == 0 ]; then
echo "Server ${network}.${sitenu} is UP."
else
echo "Server ${network}.${sitenu} is DOWN"
fi
done
[root@localhost scripts]# vi sh17.sh
[root@localhost scripts]# chmod 755 sh17.sh
[root@localhost scripts]# ./sh17.sh
Server 192.168.1.1 is UP
Server 192.168.1.2 is UP
练习4:
我想让某个用户输入某个目录文件名,然后找出某目录内的文件名的权限:
[root@localhost scripts]# vi sh18.sh
#!/bin/bash
# Program:
# user input dir name,I will find the permission of file
# History:
# 2016-11-04 ... ...
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr.local/sbin:~/bin
export PATH
# 1.先看目录是否存在
read -p "input a directory name :" dir
if [ "$dir" == "" -o ! -d "$dir" ]; then
echo "The $dir is NOT exist in your system."
exit 1
fi
# 2.开始测试文件
filelist=$(ls $dir) # 列出所有在该目录下的文件名
for filename in $filelist
do
perm=""
test -r "$dir/$filename" && perm="$perm readable"
test -w "$dir/$filename" && perm="$perm writable"
test -x "$dir/$filename" && perm="$perm executable"
echo "The file $dir/$filename's permission is $perm "
done
[root@localhost scripts]# cd
[root@localhost ~]# scripts/sh18.sh
input a directory name :scripts
The file scripts/my20161102's permission is readable writable
The file scripts/my20161103's permission is readable writable
The file scripts/my20161104's permission is readable writable
The file scripts/sh01.sh's permission is readable writable executable
The file scripts/sh02.sh's permission is readable writable executable
The file scripts/sh03.sh's permission is readable writable executable
The file scripts/sh04.sh's permission is readable writable executable
The file scripts/sh05.sh's permission is readable writable executable
The file scripts/sh06-2.sh's permission is readable writable executable
The file scripts/sh06-3.sh's permission is readable writable executable
The file scripts/sh06.sh's permission is readable writable executable
The file scripts/sh07.sh's permission is readable writable executable
The file scripts/sh08.sh's permission is readable writable executable
The file scripts/sh09-2.sh's permission is readable writable executable
The file scripts/sh09.sh's permission is readable writable executable
The file scripts/sh10.sh's permission is readable writable executable
The file scripts/sh12-2.sh's permission is readable writable executable
The file scripts/sh12-3.sh's permission is readable writable executable
The file scripts/sh12.sh's permission is readable writable executable
The file scripts/sh13-2.sh's permission is readable writable executable
The file scripts/sh13.sh's permission is readable writable executable
The file scripts/sh14.sh's permission is readable writable executable
The file scripts/sh15.sh's permission is readable writable executable
The file scripts/sh16.sh's permission is readable writable executable
The file scripts/sh17.sh's permission is readable writable executable
The file scripts/sh18.sh's permission is readable writable executable
5.3、for...do...done 的数值处理
语法:
for((初始值;限制值;执行步长))
do
#程序段
done
练习:
我们以累加1的方式计算1+2+3+...+input_number[root@localhost scripts]# vi sh19.sh
#!/bin/bash
# Program:
# Try to calculate "1+2+3+..+your_input_number"
# History:
# 2016-11-04 ... ...
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr.local/sbin:~/bin
export PATH
read -p "input a number, I will count for 1+2+3+...+your_input: " num
s=0
for((i=1;i<=$num;i=i+1))
do
s=$(($s+$i))
done
echo "The result of 1+2+...+$num is ==> $s"
[root@localhost scripts]# vi sh19.sh
[root@localhost scripts]# chmod 755 sh19.sh
[root@localhost scripts]# ./sh19.sh
input a number, I will count for 1+2+3+...+your_input: 50
The result of 1+2+...+50 is ==> 1275
6、sell script的追踪与调试
语法:
[root@localhost scripts]# sh [-nvx] scripts.sh
参数:
-n : 不执行script,仅查询语法问题
-v : 在执行script前
-x : 将使用到的script内容显示到屏幕上
范例一:
#测试sh19.sh的语法
[root@localhost scripts]# sh -n sh19.sh
#若语法无错误,则不会显示任何信息
#将执行过程列出来
[root@localhost scripts]# sh -x sh19.sh
+ PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr.local/sbin:/root/bin
+ export PATH
+ read -p 'input a number, I will count for 1+2+3+...+your_input: ' num
input a number, I will count for 1+2+3+...+your_input: 4
+ s=0
+ (( i=1 ))
+ (( i<=4 ))
+ s=1
+ (( i=i+1 ))
+ (( i<=4 ))
+ s=3
+ (( i=i+1 ))
+ (( i<=4 ))
+ s=6
+ (( i=i+1 ))
+ (( i<=4 ))
+ s=10
+ (( i=i+1 ))
+ (( i<=4 ))
+ echo 'The result of 1+2+...+4 is ==> 10'
The result of 1+2+...+4 is ==> 10
7、附录
測試的標誌 | 代表意義 |
1. 關於某個檔名的『檔案類型』判斷,如 test -e filename 表示存在否 | |
-e | 該『檔名』是否存在?(常用) |
-f | 該『檔名』是否存在且為檔案(file)?(常用) |
-d | 該『檔名』是否存在且為目錄(directory)?(常用) |
-b | 該『檔名』是否存在且為一個 block device 裝置? |
-c | 該『檔名』是否存在且為一個 character device 裝置? |
-S | 該『檔名』是否存在且為一個 Socket 檔案? |
-p | 該『檔名』是否存在且為一個 FIFO (pipe) 檔案? |
-L | 該『檔名』是否存在且為一個連結檔? |
2. 關於檔案的權限偵測,如 test -r filename 表示可讀否 (但 root 權限常有例外) | |
-r | 偵測該檔名是否存在且具有『可讀』的權限? |
-w | 偵測該檔名是否存在且具有『可寫』的權限? |
-x | 偵測該檔名是否存在且具有『可執行』的權限? |
-u | 偵測該檔名是否存在且具有『SUID』的屬性? |
-g | 偵測該檔名是否存在且具有『SGID』的屬性? |
-k | 偵測該檔名是否存在且具有『Sticky bit』的屬性? |
-s | 偵測該檔名是否存在且為『非空白檔案』? |
3. 兩個檔案之間的比較,如: test file1 -nt file2 | |
-nt | (newer than)判斷 file1 是否比 file2 新 |
-ot | (older than)判斷 file1 是否比 file2 舊 |
-ef | 判斷 file1 與 file2 是否為同一檔案,可用在判斷 hard link 的判定上。 主要意義在判定,兩個檔案是否均指向同一個 inode 哩! |
4. 關於兩個整數之間的判定,例如 test n1 -eq n2 | |
-eq | 兩數值相等 (equal) |
-ne | 兩數值不等 (not equal) |
-gt | n1 大於 n2 (greater than) |
-lt | n1 小於 n2 (less than) |
-ge | n1 大於等於 n2 (greater than or equal) |
-le | n1 小於等於 n2 (less than or equal) |
5. 判定字串的資料 | |
test -z string | 判定字串是否為 0 ?若 string 為空字串,則為 true |
test -n string | 判定字串是否非為 0 ?若 string 為空字串,則為 false。 註: -n 亦可省略 |
test str1 == str2 | 判定 str1 是否等於 str2 ,若相等,則回傳 true |
test str1 != str2 | 判定 str1 是否不等於 str2 ,若相等,則回傳 false |
6. 多重條件判定,例如: test -r filename -a -x filename | |
-a | (and)兩狀況同時成立!例如 test -r file -a -x file,則 file 同時具有 r 與 x 權限時,才回傳 true。 |
-o | (or)兩狀況任何一個成立!例如 test -r file -o -x file,則 file 具有 r 或 x 權限時,就可回傳 true。 |
! | 反相狀態,如 test ! -x file ,當 file 不具有 x 時,回傳 true |