脚本的执行方法:5种
绝对路径:#/home/shell/shell.sh
相对路径:#../shell.sh
$PATH中:#shell.sh
bash命令:#bash shell.sh
source命令(简写"."):#. shell.sh
绝对路径:#/home/shell/shell.sh
相对路径:#../shell.sh
$PATH中:#shell.sh
bash命令:#bash shell.sh
source命令(简写"."):#. shell.sh
脚本的书写:
第一行:#!/bin/bash #!叫shabang header
文件头:
脚本名、作者、联系方式、日期、changelog
定义变量:
PATH、LANG、自定义变量
定义函数:
主程序:
返回值
第一行:#!/bin/bash #!叫shabang header
文件头:
脚本名、作者、联系方式、日期、changelog
定义变量:
PATH、LANG、自定义变量
定义函数:
主程序:
返回值
返回值:
代表程序(指令、语句)的执行情况。
父进程负责收集子进程的返回值。
0 成功
非0 失败
2 用法错误
126 没权限
127 命令没找到
定义方法:
exit N
return N
查看方法:只能常上一个程序。
#echo $?
代表程序(指令、语句)的执行情况。
父进程负责收集子进程的返回值。
0 成功
非0 失败
2 用法错误
126 没权限
127 命令没找到
定义方法:
exit N
return N
查看方法:只能常上一个程序。
#echo $?
变量:
保存数据的一种形式,在内存中分配的位置。
变量名:
字母或下划线开头,后面更随字母数字或下划线。
#echo $PATH
显示 变量名
变量的定义(赋值):
变量名=值 =两边不能空格、不要用$
保存数据的一种形式,在内存中分配的位置。
变量名:
字母或下划线开头,后面更随字母数字或下划线。
#echo $PATH
显示 变量名
变量的定义(赋值):
变量名=值 =两边不能空格、不要用$
#A=123
#echo $A
#unset A 退出终端也行
#echo $A
#unset A 退出终端也行
#A=/etc/*.conf
#echo $A
#echo $A
间接引用:
#A=B
#B=helloworld
#echo ${!A} #eval echo \$$A
#A=B
#B=helloworld
#echo ${!A} #eval echo \$$A
全局变量:
#A=helloword
#export A
#export
#bash
#echo $A
helloword
#exit
#export -n A
#export | head -n 5
想永久生效的话,写配置文件/etc/[bashrc|profile]。
#A=helloword
#export A
#export
#bash
#echo $A
helloword
#exit
#export -n A
#export | head -n 5
想永久生效的话,写配置文件/etc/[bashrc|profile]。
内部变量:
PPID 父进程的PID
UID 当前用户UID
EUID 有效用户UID
BASH bash二进制文件的路径
BASH_VERSION bash版本信息
SHELL 登录shell的绝对路径
SHELLOPTS 当前shell启用的选项
EDITOR 默认编辑器
USER/LOGNAME 用户名/登录名
HOME 用户主目录
PWD 当前目录
HOSTNAME 主机名
MACHTYPE/OSTYPE 机器类型/系统类型
PATH 可执行文件的搜索路径
#PATH=$PATH:/root/bin
#export PATH
REPLY 输入数据的默认存储变量
SECONDS 脚本运行时间
RANDOM 随机数0-32767 #echo $(($RANDOM%100)) 1-100之间的随机数
PS1 第一提示符
PS2 第二提示符
PPID 父进程的PID
UID 当前用户UID
EUID 有效用户UID
BASH bash二进制文件的路径
BASH_VERSION bash版本信息
SHELL 登录shell的绝对路径
SHELLOPTS 当前shell启用的选项
EDITOR 默认编辑器
USER/LOGNAME 用户名/登录名
HOME 用户主目录
PWD 当前目录
HOSTNAME 主机名
MACHTYPE/OSTYPE 机器类型/系统类型
PATH 可执行文件的搜索路径
#PATH=$PATH:/root/bin
#export PATH
REPLY 输入数据的默认存储变量
SECONDS 脚本运行时间
RANDOM 随机数0-32767 #echo $(($RANDOM%100)) 1-100之间的随机数
PS1 第一提示符
PS2 第二提示符
$? 上一个命令的返回值
$$ 当前进程的PID
$! 最近一个后台进程的PID
$$ 当前进程的PID
$! 最近一个后台进程的PID
$0 脚本名字
$1...$N 脚本的第1个参数
$# 参数的个数
$@ 所有参数,一个一个的。"A" "B"
"$@" 所有参数,一个一个的。
$* 所有参数,一个一个的。
"$*" 所有参数,一个字符串。"A B"
#!bin/bash
echo "input something..."
read
echo $REPLY
echo '$0='$0
echo '$1='$1
echo '$10='${10} 位置变量大于10、数组、间接引用
echo '$#='$#
echo " $*=""$*"
$1...$N 脚本的第1个参数
$# 参数的个数
$@ 所有参数,一个一个的。"A" "B"
"$@" 所有参数,一个一个的。
$* 所有参数,一个一个的。
"$*" 所有参数,一个字符串。"A B"
#!bin/bash
echo "input something..."
read
echo $REPLY
echo '$0='$0
echo '$1='$1
echo '$10='${10} 位置变量大于10、数组、间接引用
echo '$#='$#
echo " $*=""$*"
bash的操作环境:
env 环境变量
set
-f 关闭路径替换
-n 读取脚本但是不执行
-e 遇到错误立刻停止
-x 打印命令替换(debug) #!/bin/bash -x
-v 打印读取的命令
stty
declare声明变量
-i 整型
-x 环境变量
-a 数组
-r 只读变量
env 环境变量
set
-f 关闭路径替换
-n 读取脚本但是不执行
-e 遇到错误立刻停止
-x 打印命令替换(debug) #!/bin/bash -x
-v 打印读取的命令
stty
declare声明变量
-i 整型
-x 环境变量
-a 数组
-r 只读变量
bash中的数组:
两个相关联的变量组成数组
array[index/key]=value
数组名 下标 元素
两个相关联的变量组成数组
array[index/key]=value
数组名 下标 元素
数组的赋值:
#array[0]=hello ; array[1]=world ; array[3]=again
#arry=(hello [4]=world [6]=again again)
数组的取值:
#echo ${array[0]}
#array[0]=hello ; array[1]=world ; array[3]=again
#arry=(hello [4]=world [6]=again again)
数组的取值:
#echo ${array[0]}
#array=(one two there four five)
#echo ${array[0]} 第一个元素的值
#echo ${array[0]:1} 第一个元素的值,从第二个字母开始显示。
#echo ${array[@]} 全部元素的值
#echo ${array[*]} 全部元素的值
#echo ${#array[0]} 第一个元素的值的长度
#echo ${#array[@]} 数组中所有元素的个数
#echo ${array[0]} 第一个元素的值
#echo ${array[0]:1} 第一个元素的值,从第二个字母开始显示。
#echo ${array[@]} 全部元素的值
#echo ${array[*]} 全部元素的值
#echo ${#array[0]} 第一个元素的值的长度
#echo ${#array[@]} 数组中所有元素的个数
#echo ${array[@]#f*r} 从左向右最短匹配,删除
#echo ${array[@]##t*e} 从左向右最长匹配,删除
#echo ${array[@]%h*e} 从右向左最短匹配,删除
#echo ${array[@]%%t*e} 从右向左最长匹配,删除
#echo ${array[@]##t*e} 从左向右最长匹配,删除
#echo ${array[@]%h*e} 从右向左最短匹配,删除
#echo ${array[@]%%t*e} 从右向左最长匹配,删除
变量的各种操纵方法:
参数替换:
${变量名-值}
${var-default} #如果变量var没有被声明,那么default就是变量var的值。
${var:-default} #如果变量var没有被赋值,那么default就是变量var的值。
#!/bin/bash
#var=
echo "${var-notdefine}"
echo "${var:-isnull}"
参数替换:
${变量名-值}
${var-default} #如果变量var没有被声明,那么default就是变量var的值。
${var:-default} #如果变量var没有被赋值,那么default就是变量var的值。
#!/bin/bash
#var=
echo "${var-notdefine}"
echo "${var:-isnull}"
${var=default}
${var:=default}
${var+default}
${var:+default}
${var?default}
${var:?default}
${var:=default}
${var+default}
${var:+default}
${var?default}
${var:?default}
变量替换:
${#var} 变量内容的长度
${var#string} 从左向右最短匹配,删除
${var##string} 从左向右最长匹配,删除
${var%string} 从右向左最短匹配,删除
${var%%string} 从右向左最长匹配,删除
#!/bin/bash
stringX=abcABC123ABCabc
echo $stringX
echo ${stringX#a*C}
echo ${stringX##a*C}
echo ${stringX%b*c}
echo ${stringX%%b*c}
#!/bin/bash
echo $0
echo ${0##*/} 保留脚本名
echo $(basename /home/shell/shell.sh) 保留脚本名
echo $MAIL
echo ${MAIL##/*/} 只保留用户名
echo ${MAIL%$USER} 只保留路径
${#var} 变量内容的长度
${var#string} 从左向右最短匹配,删除
${var##string} 从左向右最长匹配,删除
${var%string} 从右向左最短匹配,删除
${var%%string} 从右向左最长匹配,删除
#!/bin/bash
stringX=abcABC123ABCabc
echo $stringX
echo ${stringX#a*C}
echo ${stringX##a*C}
echo ${stringX%b*c}
echo ${stringX%%b*c}
#!/bin/bash
echo $0
echo ${0##*/} 保留脚本名
echo $(basename /home/shell/shell.sh) 保留脚本名
echo $MAIL
echo ${MAIL##/*/} 只保留用户名
echo ${MAIL%$USER} 只保留路径
大括号替换:
#touch file{4,9}
#touch file{0..9}
#cp /etc/fstab{,.bak}
#touch file{4,9}
#touch file{0..9}
#cp /etc/fstab{,.bak}
算术替换:
#echo $((1+ 6 ))
#echo $[1+6]
+ - * / % ()
#SUM=`bc <<<"1+7"`
#echo $SUM
#echo $((1+ 6 ))
#echo $[1+6]
+ - * / % ()
#SUM=`bc <<<"1+7"`
#echo $SUM
命令替换:
`command`
$(command)
#rpm -qf `which httpd` httpd命令是哪个软件包安装的?
`command`
$(command)
#rpm -qf `which httpd` httpd命令是哪个软件包安装的?
各种比较:
test(简写"[","]")命令
文件类型:#test -e filename #[ -e filename ]
-e 是否存在
-f 是否为文件
-d 是否为目录
-b 是否为块设备
-c 是否为字符设备
-S 是否为socket文件
-p 是否为管道
-L 是否为连接
文件权限:
-r
-w
-x
-u 是否有SUID
-g 是否有SGID
-k 是否有Sticky bit
-s 是否非空
两个文件之间:#test file1 -nt file2
-nt file1是否比file2新
-ot file1是否比file2旧
-ef 两个文件是否相同
整数之间:
-eq 相等
-ne 不等
-gt 大于
-lt 小于
-ge 大于等于
-le 小于等于
字符、字符串之间:
-z 是否空
-n 是否非空
== 相同
!= 不同
其他:#test -r file1 -a -x file1 #test ! -e file1
-a 逻辑于
-o 逻辑或
! 非(取反)
例:
test.sh
test(简写"[","]")命令
文件类型:#test -e filename #[ -e filename ]
-e 是否存在
-f 是否为文件
-d 是否为目录
-b 是否为块设备
-c 是否为字符设备
-S 是否为socket文件
-p 是否为管道
-L 是否为连接
文件权限:
-r
-w
-x
-u 是否有SUID
-g 是否有SGID
-k 是否有Sticky bit
-s 是否非空
两个文件之间:#test file1 -nt file2
-nt file1是否比file2新
-ot file1是否比file2旧
-ef 两个文件是否相同
整数之间:
-eq 相等
-ne 不等
-gt 大于
-lt 小于
-ge 大于等于
-le 小于等于
字符、字符串之间:
-z 是否空
-n 是否非空
== 相同
!= 不同
其他:#test -r file1 -a -x file1 #test ! -e file1
-a 逻辑于
-o 逻辑或
! 非(取反)
例:
test.sh
各种杂项:
echo:
#echo -ne "hello\tworld\n"
read:
-p 显示提示信息 #read -p "Input filename:" FN
-t 超时时间
-n 1 按任意键继续
sleep/wait: #sleep 5
exit/return:
:
bc: #bc <<<"1+7"
seq: #seq 6 #seq 2 6 #seq 1 2 9
各种语句:
if:
if CONDITION
then
COMMAND
fi
if CONDITION
then
COMMAND1
else
COMMAND2
fi
if CONDITION1
then
COMMAND1
elif CONDITION2
then
COMMAND2
else
COMMAND3
fi
例:
#!/bin/bash
if [ -d $1 ] ; then
echo "$1 is directory."
elif [ -x $1 ] ; then
echo "$1 is a scripts."
elif [ -f $1 ] ; then
echo "$1 is a file."
else
echo "Unknown."
fi
例子:
有木有.sh
例子:
计算闰年
leapyear.sh
for:
for VAR in LIST
do
COMMANDS
done
LIST的写法:
直接写: for i in 1 2 3
大括号扩展:for i in {0..99}
通配符:for i in /etc/*.conf
命令的结果:for i in `find /etc/ -name "*.conf"`
C风格:for ((i=0;i<10;i=i+1))
练:
#!/bin/bash
for A in $@ ; do
echo '$@='$A
done
for B in "$@" ; do
echo '" $@"='$B
done
for C in $* ; do
echo '$*='$C
done
for D in "$*" ; do
echo '"$*"='$D
done
for i in ${array[@]} ; do
echo $i
done
例:
9*9.sh
#!/bin/bash
for i in {1..9} ; do
for n in `seq 1 $i` ; do
echo -ne "$i*$n=$(($i*$n))"
done
echo
done
ping.sh
方法一:
#!/bin/bash
for i in {252..254} ; do
ping -c1 192.168.18.$i &> /dev/null
if [ "$?" == "0" ] ; then
echo "192.168.18.$i online."
else
echo "192.168.18.$i offline."
fi
done
方法二:
for i in {252..254} ; do
if ping -c1 192.168.18.$i &> /dev/null ; then
echo "192.168.18.$i online."
else
echo "192.168.18.$i offline."
fi
done
方法三:
for i in {252..254} ; do
result=`ping -c1 192.168.18.$i | grep ttl | cut -d "=" -f 2 | cut -d " " -f 2`
if [ "$result" == "ttl" ] ; then
echo "192.168.18.$i online."
else
echo "192.168.18.$i offline."
fi
done
mssh.sh
#!/bin/bash
#mssh.sh "IP1 IP2" "service iptables stop"
for i in $1 ; do
ssh $i $2
done
监控磁盘
#!/bin/bash
for space in `LANG=C df -h | grep -v Use | awk '{print $5}' | cut -d "%" -f 1`
do
if [ $space -get 80 ] ; then
echo "Over 80%" | mail -s "report" root@localhost
else
echo "Disk space normail" | mail -s "report" root@localhost
fi
done
for VAR in LIST
do
COMMANDS
done
LIST的写法:
直接写: for i in 1 2 3
大括号扩展:for i in {0..99}
通配符:for i in /etc/*.conf
命令的结果:for i in `find /etc/ -name "*.conf"`
C风格:for ((i=0;i<10;i=i+1))
练:
#!/bin/bash
for A in $@ ; do
echo '$@='$A
done
for B in "$@" ; do
echo '" $@"='$B
done
for C in $* ; do
echo '$*='$C
done
for D in "$*" ; do
echo '"$*"='$D
done
for i in ${array[@]} ; do
echo $i
done
例:
9*9.sh
#!/bin/bash
for i in {1..9} ; do
for n in `seq 1 $i` ; do
echo -ne "$i*$n=$(($i*$n))"
done
echo
done
ping.sh
方法一:
#!/bin/bash
for i in {252..254} ; do
ping -c1 192.168.18.$i &> /dev/null
if [ "$?" == "0" ] ; then
echo "192.168.18.$i online."
else
echo "192.168.18.$i offline."
fi
done
方法二:
for i in {252..254} ; do
if ping -c1 192.168.18.$i &> /dev/null ; then
echo "192.168.18.$i online."
else
echo "192.168.18.$i offline."
fi
done
方法三:
for i in {252..254} ; do
result=`ping -c1 192.168.18.$i | grep ttl | cut -d "=" -f 2 | cut -d " " -f 2`
if [ "$result" == "ttl" ] ; then
echo "192.168.18.$i online."
else
echo "192.168.18.$i offline."
fi
done
mssh.sh
#!/bin/bash
#mssh.sh "IP1 IP2" "service iptables stop"
for i in $1 ; do
ssh $i $2
done
监控磁盘
#!/bin/bash
for space in `LANG=C df -h | grep -v Use | awk '{print $5}' | cut -d "%" -f 1`
do
if [ $space -get 80 ] ; then
echo "Over 80%" | mail -s "report" root@localhost
else
echo "Disk space normail" | mail -s "report" root@localhost
fi
done
while:#true #false
while CONTROL-COMMAND
do
CONSEQUENT-COMMANDS
done
例:
#!/bin/bash
i=0
while [ $i -lt 4 ] ; do
echo $i
i=$[$i+1]
done
until:
until CONTROL-COMMAND
do
CONSEQUENT-COMMANDS
done
例:
#!/bin/bash
num=1
until [ ! "$num" -le 5 ] ; then
do
echo "$num"
num=$(($num+1))
done
练:
监控httpd是否运行,没运行的话尝试重启并发邮件报警。
#!/bin/bash
process=httpd
while true ; do
#result=`pstree | grep $process`
pstree | grep $process &> /dev/null
if [ $? -eq 0 ] ; then
echo "$process is running." | mail -s "report" root@localhost
else
echo "$process NOT running." | mail -s "report" root@localhost
fi
sleep 600
done
while CONTROL-COMMAND
do
CONSEQUENT-COMMANDS
done
例:
#!/bin/bash
i=0
while [ $i -lt 4 ] ; do
echo $i
i=$[$i+1]
done
until:
until CONTROL-COMMAND
do
CONSEQUENT-COMMANDS
done
例:
#!/bin/bash
num=1
until [ ! "$num" -le 5 ] ; then
do
echo "$num"
num=$(($num+1))
done
练:
监控httpd是否运行,没运行的话尝试重启并发邮件报警。
#!/bin/bash
process=httpd
while true ; do
#result=`pstree | grep $process`
pstree | grep $process &> /dev/null
if [ $? -eq 0 ] ; then
echo "$process is running." | mail -s "report" root@localhost
else
echo "$process NOT running." | mail -s "report" root@localhost
fi
sleep 600
done
case
break continue
shift
函数
锁
autoinstall.sh
本文转自zhaoyun00 51CTO博客,原文链接:http://blog.51cto.com/zhaoyun/747166