linux bash脚本编程知识点

bash变量类型:
环境变量
本地变量(局部变量)
位置变量
特殊变量

本地变量:
set VARNAME=VALUE: 作用域为整个bash进程;
引用变量 $(varname)
局部变量:
local VARNAME=VALUE:作用域为当前代码段;


环境变量:作用域为当前shell进程及其子进程;
export VARNAM
E=VALUE
VARNAME=VALUE
export VARNAME
“导出”
脚本在执行时会启动一个子shell进程
命令行中启动的脚本会继承当前shell环境变量
系统自动执行的脚本(非命令行启动)就需要自我定义需要各环境变量


位置变量:
$1, $2, ...


$?: 保存上一个命令的执行状态返回值;


程序执行,可能有两类返回值:
程序执行结果
程序状态返回代码(0-255)
0: 正确执行
1-255:错误执行,1,2,127系统预留;




撤消变量:
unset VARNAME


查看当shell中变量:
set


查看当前shell中的环境变量:
printenv
env
export


脚本:命令的堆砌,按实际需要,结合命令流程控制机制实现的源程序


shebang: 魔数
#!/bin/bash
# 注释行,不执行






/dev/null: 软件设备, bit bucket,数据黑洞



脚本在执行时会启动一个子shell进程;
命令行中启动的脚本会继承当前shell环境变量;






练习:写一个脚本,完成以下任务
1、添加5个用户, user1,..., user5
2、每个用户的密码同用户名,而且要求,添加密码完成后不显示passwd命令的执行结果信息;
3、每个用户添加完成后,都要显示用户某某已经成功添加;
useradd user1
echo "user1" | passwd --stdin user1 &> /dev/null
echo "Add user1 successfully."




条件判断:
如果用户不存在
添加用户,给密码并显示添加成功;
否则
显示如果已经没在,没有添加;


bash中如何实现条件判断?
条件测试类型:
整数测试
字符测试
文件测试


条件测试的表达式:
[ expression ]
[[ expression ]]
test expression

整数比较:
-eq: 测试两个整数是否相等;比如 $A -eq $B
-ne: 测试两个整数是否不等;不等,为真;相等,为假;
-gt: 测试一个数是否大于另一个数;大于,为真;否则,为假;
-lt: 测试一个数是否小于另一个数;小于,为真;否则,为假;
-ge: 大于或等于
-le:小于或等于

命令的间逻辑关系:
逻辑与: &&
第一个条件为假时,第二条件不用再判断,最终结果已经有;
第一个条件为真时,第二条件必须得判断;
逻辑或: ||

如果用户user6不存在,就添加用户user6
! id user6 && useradd user6
id user6 || useradd user6


如果/etc/inittab文件的行数大于100,就显示好大的文件;
[ `wc -l /etc/inittab | cut -d' ' -f1` -gt 100 ] && echo "Large file."


变量名称:
1、只能包含字母、数字和下划线,并且不能数字开头;
2、不应该跟系统中已有的环境变量重名;
3、最好做到见名知义;


如果用户存在,就显示用户已存在;否则,就添加此用户;
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、添加完成后,显示一共添加了几个用户;当然,不能包括因为事先存在而没有添加的;
3、最后显示当前系统上共有多少个用户;


如果 UID为0;那么
  显示为管理员
否则
  显示为普通用户
  
NAME=user16
USERID=`id -u $NAME`
if [ $USERID -eq 0 ]; then
  echo "Admin"
else
  echo "common user."
fi//结束






NAME=user16
if [ `id -u $NAME` -eq 0 ]; then
  echo "Admin"
else
  echo "common user."
fi


练习:写一个脚本
判断当前系统上是否有用户的默认shell为bash;
   如果有,就显示有多少个这类用户;否则,就显示没有这类用户;
#!/bin/bash
#
grep "\ /dev/null
RETVAL=$?
if [ $RETVAL -eq 0 ]; then
grep "\ else
echo "No such user."
fi

练习:写一个脚本
给定一个文件,比如/etc/inittab 
判断这个文件中是否有空白行;
如果有,则显示其空白行数;否则,显示没有空白行。
#!/bin/bash
A=`grep '^$' /etc/inittab | wc -l`
if [ $A -gt 0 ]; then
 echo "$A"
else
 echo "meiyoukongbaihang"
fi
                
 
#!/bin/bash
FILE=/etc/inittab
if [ ! -e $FILE ]; then
  echo "No $FILE."
  exit 8
fi


if grep "^$" $FILE &> /dev/null; then
  echo "Total blank lines: `grep "^$" $FILE | wc -l`." 
else
  echo "No blank line."
fi


练习:写一个脚本
给定一个用户,判断其UID与GID是否一样
如果一样,就显示此用户为“good guy”;否则,就显示此用户为“bad guy”。
#!/bin/bash
USERNAME=user1
USERID=`id -u $USERNAME`
GROUPID=`id -g $USERNAME`
if [ $USERID -eq $GROUPID ]; then
  echo "Good guy."
else
  echo "Bad guy."
fi


进一步要求:不使用id命令获得其id号;


#!/bin/bash
#
USERNAME=user1
if ! grep "^$USERNAME\>" /etc/passwd &> /dev/null; then
  echo "No such user: $USERNAME."
  exit 1
fi


USERID=`grep "^$USERNAME\>" /etc/passwd | cut -d: -f3`
GROUPID=`grep "^$USERNAME\>" /etc/passwd | cut -d: -f4`
if [ $USERID -eq $GROUPID ]; then
  echo "Good guy."
else
  echo "Bad guy."
fi


练习:写一个脚本
给定一个用户,获取其密码警告期限;
而后判断用户密码使用期限是否已经小于警告期限;
提示:计算方法,最长使用期限减去已经使用的天数即为剩余使用期限;

如果小于,则显示“Warning”;否则,就显示“OK”。


圆整:丢弃小数点后的所有内容


#!/bin/bash
W=`grep "student" /etc/shadow | cut -d: -f6`
S=`date +%s`
T=`expr $S/86400`
L=`grep "^student" /etc/shadow | cut -d: -f5`
N=`grep "^student" /etc/shadow | cut -d: -f3`
SY=$[$L-$[$T-$N]]


if [ $SY -lt $W ]; then
  echo 'Warning'
else
  echo 'OK'
fi




练习:写一个脚本
判定命令历史中历史命令的总条目是否大于1000;如果大于,则显示“Some command will gone.”;否则显示“OK”。


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`


条件判断,控制结构:


单分支if语句
if 判断条件; then
  statement1
  statement2
  ...
fi


双分支的if语句:
if 判断条件; then
statement1
statement2
...
else
statement3
statement4
...
fi


多分支的if语句:
if 判断条件1; then
  statement1
  ...
elif 判断条件2; then
  statement2
  ...
elif 判断条件3; then
  statement3
  ...
else
  statement4
  ...
fi






测试方法:
[ expression ]
[[ expression ]]
test expression


bash中常用的条件测试有三种:
整数测试:
-eq: 测试两个整数是否相等;比如 $A -eq $B
-ne: 测试两个整数是否不等;不等,为真;相等,为假;
-gt: 测试一个数是否大于另一个数;大于,为真;否则,为假;
-lt: 测试一个数是否小于另一个数;小于,为真;否则,为假;
-ge: 大于或等于
-le:小于或等于


INT1=63
INT2=77
[ $INT1 -eq $INI2 ]
[[ $INT1 -eq $INT2 ]]
test $INT1 -eq $INT2  

文件测试:
-e FILE:测试文件是否存在
-f FILE: 测试文件是否为普通文件
-d FILE: 测试指定路径是否为目录
-r FILE: 测试当前用户对指定文件是否有读取权限;
-w
-x


[ -e /etc/inittab ]
[ -x /etc/rc.d/rc.sysinit ]


练习:写一个脚本
给定一个文件:
如果是一个普通文件,就显示之;
如果是一个目录,亦显示之;
否则,此为无法识别之文件;


定义脚本退出状态码


exit: 退出脚本
exit #
如果脚本没有明确定义退出状态码,那么,最后执行的一条命令的退出码即为脚本的退出状态码;




测试脚本是否有语法错误:
bash -n 脚本


bash -x 脚本:单步执行






bash变量的类型:
本地变量:
set VARNAME=VALUE: 作用域为整个bash进程;
引用变量 $(varname)
局部变量:
local VARNAME=VALUE:作用域为当前代码段;


环境变量:作用域为当前shell进程及其子进程;
export VARNAME=VALUE
VARNAME=VALUE
export VARNAME
“导出”
脚本在执行时会启动一个子shell进程
命令行中启动的脚本会继承当前shell环境变量
系统自动执行的脚本(非命令行启动)就需要自我定义需要各环境变量
位置变量: 
$1, $2, ...
shift
特殊变量:
$?
$#:参数的个数
$*: 参数列表
$@:参数列表

./filetest.sh /etc/fstab /etc/inittab
$1: /etc/fstab
$2: /etc/inittab


练习:写一脚本
能接受一个参数(文件路径)
判定:此参数如果是一个存在的文件,就显示“OK.”;否则就显示"No such file."


练习:写一个脚本
给脚本传递两个参数(整数);
显示此两者之和,之乘积;
#!/bin/bash
#
if [ $# -lt 2 ]; then
  echo "Usage: cacl.sh ARG1 ARG2"
  exit 8
fi


echo "The sum is: $[$1+$2]."
echo "The prod is: $[$1*$2]."



练习:写一个脚本,完成以下任务
1、使用一个变量保存一个用户名;
2、删除此变量中的用户,且一并删除其家目录;
3、显示“用户删除完成”类的信息


bash: 


引用变量:${VARNAME}, 括号有时可省略。

整型,8bit: 256
0-255, 溢出

变量:
1,10000
10:16bit
10: 1010, 8bit

编程能力:
脚本编程

#abc
# hello world
   # hi world

练习:
传递一个用户名参数给脚本,判断此用户的用户名跟其基本组的组名是否一致,并将结果显示出来。

字符测试:
==:测试是否相等,相等为真,不等为假
!=: 测试是否不等,不等为真,等为假
>
<
-n string: 测试指定字符串 是否为空,空则真,不空则假
-z string: 测试指定字符串是否不空,不空为真,空则为假


练习:写一个脚本
传递一个参数(单字符就行)给脚本,如参数为q,就退出脚本;否则,就显示用户的参数;


练习:写一个脚本
传递一个参数(单字符就行)给脚本,如参数为q、Q、quit或Quit,就退出脚本;否则,就显示用户的参数;
#!/bin/bash
#
if [ $1 = 'q' ];then
  echo "Quiting..."
  exit 1
elif [ $1 = 'Q' ];then
  echo "Quiting..."
  exit 2  
elif [ $1 = 'quit' ];then
  echo "Quiting..."
  exit 3 
elif [ $1 = 'Quit' ];then
  echo "Quiting..."
  exit 4  
else
  echo $1
fi




练习:
if [ $# -lt 2 ];
传递三个参数给脚本,第一个为整数,第二个为算术运算符,第三个为整数,将计算结果显示出来,要求保留两位精度。形如:
./calc.sh 5 / 2


#!/bin/bash
#
A=$1
x=$2
B=$3
result= echo "scale=2;$A$x$B;"|bc
echo $result


etco "scale=2;111/22" | bc   //结果为5.04


练习:
传递3个参数给脚本,参数均为用户名。将此些用户的帐号信息提取出来后放置于/tmp/testusers.txt文件中,并要求每一行行首有行号。
egrep “$1|$2|$3” /etc/passwd >>/tmp/a
cat ?n /tmp/a > /tmp/test0
rm ?rf a


写一个脚本:
判断当前主机的CPU生产商,其信息在/proc/cpuinfo文件中vendor id一行中。
如果其生产商为AuthenticAMD,就显示其为AMD公司;
如果其生产商为GenuineIntel,就显示其为Intel公司;
否则,就说其为非主流公司;
#!/bin/bash
VENDOR_ID=`grep vendor_id /proc/cpuinfo | head -1 | cut -d' ' -f2` 
if [ $VENDOR_ID == "AuthenticAMD" ]; then
    echo "AMD company"
elif [ $VENDOR_ID == "GenuineIntel" ]; then
    echo "Intel company"
fi


写一个脚本:
给脚本传递三个整数,判断其中的最大数和最小数,并显示出来。
MAX=0
MAX -eq $1
MAX=$1
MAX -lt $2
MAX=$2
例:比较三个数的大小


echo -n "Enter three number:"
read a b c
if [ $a -gt $b ];then
 t=$a;a=$b;b=$t;
fi
if [ $a -gt $c ];then
 t=$a;a=$c;c=$t;
fi
if [ $b -gt $c ];then
 t=$b;b=$c;c=$t;
fi
echo "From small to big:$a,$b,$c"




例:求1到100的和
#!/bin/bash
declare  -i SUM=0
for I in {1..100};do
      SUM=$[$SUM+$I]
done
echo “The SUM is :$SUM。”


循环:进入条件,退出条件
for
while
until


for 变量 in 列表; do
  循环体
done


for I in 1 2 3 4 5 6 7 8 9 10; do
  加法运算
done


遍历完成之后,退出;


如何生成列表:
{1..100}
`seq [起始数 [步进长度]] 结束数`

1,...,100


declare -i SUM=0
integer
-x//环境变量

写一个脚本:
1、设定变量FILE的值为/etc/passwd
2、依次向/etc/passwd中的每个用户问好,并显示对方的shell,形如:  
Hello, root, your shell: /bin/bash
#!/bin/bash
for I in `cat /etc/passwd |grep 'bash'`;do
       echo"hello `echo $I |cut -d: -f1` your bash"
done
3、统计一共有多少个用户


for I in `seq 1 $LINES`; do echo "Hello, `head -n $I /etc/passwd | tail -1 | cut -d: -f1`"; done


只向默认shell为bash的用户问声好




写一个脚本:
1、添加10个用户user1到user10,密码同用户名;但要求只有用户不存在的情况下才能添加;
#!/bin/bash
if [ $1 == add];then
for I in{1..10};do
       ! id user$I &&useradd user$I -puser$I
done
elif [ $1 == del];then
       for I in {1..10};do
              id user$I >/dev/null &&userdel user$I
       done
else
       echo "paramiter wrong"
fi
扩展:
接受一个参数:
add: 添加用户user1..user10
del: 删除用户user1..user10
其它:退出
adminusers user1,user2,user3,hello,hi

写一个脚本:
计算100以内所有能被3整除的正整数的和;
取模,取余:%
3%2=1
100%55=45

写一个脚本:
let I=$[$I+1]
SUM=$[$SUM+$I]

let SUM+=$I


let I+=1 相当于 let I++

-=
let I-=1 相当于 let I--

++I, --I

*=
/=
%=

测试:
整数测试:
-eq: 测试两个整数是否相等;比如 $A -eq $B
-ne: 测试两个整数是否不等;不等,为真;相等,为假;
-gt: 测试一个数是否大于另一个数;大于,为真;否则,为假;
-lt: 测试一个数是否小于另一个数;小于,为真;否则,为假;
-ge: 大于或等于
-le:小于或等于
字符测试:
==:测试是否相等,相等为真,不等为假
!=: 测试是否不等,不等为真,等为假
>
<
-n string: 测试指定字符串 是否为空,空则真,不空则假
-z string: 测试指定字符串是否不空,不空为真,空则为假

文件测试:
-e FILE:测试文件是否存在
-f FILE: 测试文件是否为普通文件
-d FILE: 测试指定路径是否为目录
-r FILE: 测试当前用户对指定文件是否有读取权限;
-w
-x

if [ $# -gt 1 ]; then


组合测试条件
-a: 与关系
-o: 或关系
!: 非关系

if [ $# -gt 1 -a $# -le 3 ]
if [ $# -gt 1 ] && [ $# -le 3 ]


生成随机数 
RANDOM: 0-32768


随机数生成器:熵池
/dev/random:
/dev/urandom:


写一个脚本,利用RANDOM生成10个随机数,并找 出其中的最大值,和最小值;
#!/bin/bash
#
declare -i MAX=0
declare -i MIN=0


for I in {1..10}; do
  MYRAND=$RANDOM
  [ $I -eq 1 ] && MIN=$MYRAND
  if [ $I -le 9 ]; then
    echo -n "$MYRAND,"
  else
    echo "$MYRAND"
  fi
  [ $MYRAND -gt $MAX ] && MAX=$MYRAND
  [ $MYRAND -lt $MIN ] && MIN=$MYRAND
done


echo $MAX, $MIN


面向过程
控制结构
顺序结构
选择结构
循环结构


选择结构:
if: 单分支、双分支、多分支
if CONDITION; then
  statement
  ...
fi


if CONDITION; then
  statement
  ...
else
  statement
  ...
fi


if CONDITION1; then
  statement
  ...
elif CONDITION2; then
  statement
  ...
esle
  statement
  ...
fi




case语句:选择结构


case SWITCH in 
value1)
  statement
  ...
  ;;
value2)
  statement
  ...
  ;;
*)
  statement
  ...
  ;;
esac


a-z
A-Z
0-9
[abc]


只接受参数start,stop,restart,status其中之一
#!/bin/bash
#
DEBUG=0
ADD=0
DEL=0


for I in `seq 0 $#`; do
  if [ $# -gt 0 ]; then
 case $1 in
 -v|--verbose)
DEBUG=1
shift ;;
 -h|--help)
echo "Usage: `basename $0` --add USER_LIST --del USER_LIST -v|--verbose -h|--help"
exit 0
;;
 --add)
ADD=1
ADDUSERS=$2
shift 2
;;
 --del)
DEL=1
DELUSERS=$2
shift 2
;;
 *)
echo "Usage: `basename $0` --add USER_LIST --del USER_LIST -v|--verbose -h|--help"
exit 7
;;
    esac
  fi
done


if [ $ADD -eq 1 ]; then
  for USER in `echo $ADDUSERS | sed 's@,@ @g'`; do
    if id $USER &> /dev/null; then
      [ $DEBUG -eq 1 ] && echo "$USER exists."
    else
      useradd $USER
      [ $DEBUG -eq 1 ] && echo "Add user $USER finished."
    fi
  done
fi


if [ $DEL -eq 1 ]; then
  for USER in `echo $DELUSERS | sed 's@,@ @g'`; do
    if id $USER &> /dev/null; then
      userdel -r $USER
      [ $DEBUG -eq 1 ] && echo "Delete $USER finished."
    else
      [ $DEBUG -eq 1 ] && echo "$USER not exist."
    fi
  done
fi


练习:写一个脚本showlogged.sh,其用法格式为:
showlogged.sh -v -c -h|--help
其中,-h选项只能单独使用,用于显示帮助信息;-c选项时,显示当前系统上登录的所有用户数;如果同时使用了-v选项,则既显示同时登录的用户数,又显示登录的用户的相关信息;如
Logged users: 4. 


They are:
root     tty2         Feb 18 02:41
root     pts/1        Mar  8 08:36 (172.16.100.177)
root     pts/5        Mar  8 07:56 (172.16.100.177)
hadoop   pts/6        Mar  8 09:16 (172.16.100.177)


#!/bin/bash
#
declare -i SHOWNUM=0
declare -i SHOWUSERS=0


for I in `seq 1 $#`; do
  if [ $# -gt 0 ]; then
    case $1 in
    -h|--help)
      echo "Usage: `basename $0` -h|--help -c|--count -v|--verbose"
      exit 0 ;;
    -v|--verbose)
      let SHOWUSERS=1
      shift ;;
    -c|--count)
      let SHOWNUM=1
      shift ;;
    *)
      echo "Usage: `basename $0` -h|--help -c|--count -v|--verbose"
      exit 8 ;;
    esac
  fi
done


if [ $SHOWNUM -eq 1 ]; then
  echo "Logged users: `who | wc -l`."
  if [ $SHOWUSERS -eq 1 ]; then
    echo "They are:"
    who
  fi
fi


脚本编程:
顺序结构
选择结构
if
case
循环结构
for
while
until

while循环:适用于循环次数未知的场景,要有退出条件
语法:
while CONDITION; do
 statement
 ...
done

计算100以内所有正整数的和


#!/bin/bash
declare -i I=1
declare -i SUM=0


while [ $I -le 100 ]; do
  let SUM+=$I
  let I++
done


echo $SUM


练习:转换用户输入的字符为大写,除了quit:
#!/bin/bash
#
read -p "Input something: " STRING


while [ $STRING != 'quit' ]; do
  echo $STRING | tr 'a-z' 'A-Z'
  read -p "Input something: " STRING
done


练习:每隔5秒查看hadoop用户是否登录,如果登录,显示其登录并退出;否则,显示当前时间,并说明hadoop尚未登录:
#!/bin/bash
#
who | grep "hadoop" &> /dev/null
RETVAL=$?


while [ $RETVAL -ne 0 ]; do
  echo "`date`, hadoop is not log." 
  sleep 5
  who | grep "hadoop" &> /dev/null
  RETVAL=$?
done


echo "hadoop is logged in."


写一个脚本:
1) 显示一个菜单给用户: 
d|D) show disk usages.
m|M) show memory usages.
s|S) show swap usages.
*) quit.
2) 当用户给定选项后显示相应的内容;
   
扩展:
当用户选择完成,显示相应信息后,不退出;而让用户再一次选择,再次显示相应内容;除了用户使用quit;
#!/bin/bash
#
cat << EOF
d|D) show disk usages.
m|M) show memory usages.
s|S) show swap usages.
*) quit.
EOF


read -p "Your choice: " CHOICE
while [ $CHOICE != 'quit' ];do
  case $CHOICE in
  d|D)
    echo "Disk usage: "
    df -Ph ;;
  m|M)
    echo "Memory usage: "
    free -m | grep "Mem" ;;
  s|S)
    echo "Swap usage: "
    free -m | grep "Swap" ;;
  *)
    echo "Unknown.." ;;
  esac


read -p "Again, your choice: " CHOICE
done

脚本编程控制结构:
顺序
选择
if
case
循环
for 
while
until


while CONDITION; do
  statment
done


进入循环:条件满足
退出循环:条件不满足

until CONDITION; do
  statement
  ...
done


进入循环:条件不满足
退出循环:条件满足


for 变量 in 列表; do 
循环体
done

for (( expr1 ; expr2 ; expr3 )); do 
  循环体
done

写一个脚本:
1、通过ping命令测试192.168.0.151到192.168.0.254之间的所有主机是否在线,
如果在线,就显示"ip is up.",其中的IP要换为真正的IP地址,且以绿色显示;
如果不在线,就显示"ip is down.",其中的IP要换为真正的IP地址,且以红色显示;


要求:分别使用while,until和for(两种形式)循环实现。




写一个脚本,完成以下功能:
1、提示用户输入一个用户名;
2、显示一个菜单给用户,形如:
cat < U|u  show UID
G|g  show GID
S|s  show SHELL
Q|q  quit
EOF
 #!bin/bash
      2 #
      3 cat << EOF
      4 U|u  show UID
      5 G|g  show GID
      6 S|s  show SHELL
      7 Q|q  quit
      8 EOF
      9 read -p "You choice: " CHOICE
     10 until [ $CHOICE == 'q' -o $CHOICE == 'Q' ]
     11 do
     12 case $CHOICE in
     13 d|D) df -lh;;
     14 m|M) free -m | grep "^Mem";;
     15 s|S) free -m | grep "^Swap";;
     16 *) read -p "You choice,again: " CHOICE;;
     17 esac
     18 read -p "You choice: " CHOICE
     19 done

函数:功能, function


代码重用:


库:so




脚本编程之函数:


function: 功能


结构化编程,不能独立运行,需要调用时执行,可以被多次调用


定义一个函数:
function FUNCNAME {
  command
}


FUNCNAME() {
  command
}




自定义执行状态返回值:
return #
0-255


接受参数的函数:
./a.sh m n 
$1: m
$2: n


sum()
{
echo $1+$2
TWOINT 5 6


$1: 5
$2: 6


练习:写一个脚本,判定192.168.0.200-192.168.0.254之间的主机哪些在线。要求:
1、使用函数来实现一台主机的判定过程;
2、在主程序中来调用此函数判定指定范围内的所有主机的在线情况。


#!/bin/bash
#
PING() {
  for I in {200..254};do
    if ping -c 1 -W 1 192.168.0.$I &> /dev/null; then
      echo "192.168.0.$I is up."
    else
      echo "192.168.0.$I is down."
    fi
  done
}


PING

#!/bin/bash
#
PING() {
    if ping -c 1 -W 1 $1 &> /dev/null; then
      echo "$1 is up."
    else
      echo "$1 is down."
    fi
}


for I in {200..254}; do
  PING 192.168.0.$I
done




#!/bin/bash
#
PING() {
    if ping -c 1 -W 1 $1 &> /dev/null; then
      return 0
    else
      return 1
    fi
}


for I in {200..254}; do
  PING 192.168.0.$I
  if [ $? -eq 0 ]; then
    echo "192.168.0.$I is up."
  else
    echo "192.168.0.$I is down."
  fi
done




写一个脚本:使用函数完成
1、函数能够接受一个参数,参数为用户名;
   判断一个用户是否存在
   如果存在,就返回此用户的shell和UID;并返回正常状态值;
   如果不存在,就说此用户不存在;并返回错误状态值;
2、在主程序中调用函数;


扩展1:在主程序中,让用户自己输入用户名后,传递给函数来进行判断;
扩展2:在主程序中,输入用户名判断后不退出脚本,而是提示用户继续输入下一个用户名;如果用户输入的用户不存在,请用户重新输入;但如果用户输入的是q或Q就退出;


#!/bin/bash
#
user () {
if id $1 &> /dev/null ;then
echo "`grep ^$1  /etc/passwd | cut -d: -f3,7`"
   return 0
else
   echo "no $1"
    return 1
fi
}
read -p "please input username:" username
until [ $username == q -o $username == Q ]; do
user $username
if [ $? == 0 ];then
read -p "please input again:" username
else
read -p "no $username,please input again:" username
fi
done



函数也可以接受参数, 即可以向函数传递参数




函数接受一个用户名参数,显示此用户的shell和UID;

写一个函数:接受一命令参数ls


/bin/ls, /mnt/sysroot/bin/ls


/sbin/ifconfig, /mnt/sysroot/sbin/ifconfig

脚本编程知识点:
1、变量中字符的长度:${#VARNAME}
2、变量赋值等:
${parameter:-word}:如果parameter为空或未定义,则变量展开为“word”;否则,展开为parameter的值;
${parameter:+word}:如果parameter为空或未定义,不做任何操作;否则,则展开为“word”值;
${parameter:=word}:如果parameter为空或未定义,则变量展开为“word”,并将展开后的值赋值给parameter;
${parameter:offset}
${parameter:offset:length}:取子串,从offset处的后一个字符开始,取lenth长的子串;


3、脚本配置文件
/etc/rc.d/init.d/服务脚本
服务脚本支持配置文件:/etc/sysconfig/服务脚本同名的配置文件
.conf为配置文件。
#!/bin/bash
#
./root/a.conf  //把a.conf这个文件加载进来


4、局部变量
local VAR_NAME=//必须用local


a=1


test() {
  a=$[3+4]
}


test
for I in `seq $a 10`; do
  echo $I
done  


5、命令mktemp
创建临时文件或目录


mktemp /tmp/file.XX
-d: 创建为临时目录

6、信号
kill -SIG(NAL) PID
1: HUP
2: INT//终止
9: KILL
15: TERM

脚本中,能实现信号捕捉,但9和15无法捕捉


Ctrl+c: SIGINT


trap命令:
trap 'COMMAND' 信号列表 

7、一行执行多个语句,语句间用分号分隔

你可能感兴趣的:(linux)