Linux SHELL 脚本编程详解
Linux SHELL 脚本编程
- 脚本编程详解
- 名词解释
- shell 脚本
- 脚本中的条件测试
- bash 测试分类
- 脚本的状态返回值
- 脚本语法检测和调试执行
- 编程脚本之用户交互
- 脚本执行方式
- 1、选择执行
- if 语句
- case 语句
- 2、循环执行
- 2.1 for 循环
- LIST 列表的生成方式
- for 循环 示例
- for 循环的特殊用法
- 2.2 while 循环
- 2.3 until 循环
- 脚本示例
- 1、vim 如何定制自动缩进四个字符。
- 2、实现自动添加三个用户,并计算这三个用户的 uid 之和。
- 3、通过命令传递两个文本文件路径给脚本,计算其空白行数之和。
- 4、通过参数传递一个用户名给脚本,此用户不存时,则添加之。
- 5、通过命令行参数给定两个数字,输出其中较大的数值。
- 6、脚本参数传递一个文件路径给脚本,判断此文件的类型。
- 7、传递一个参数给脚本,此参数为用户名;根据其ID号来判断用户类型。
- 8、写一个脚本,要求如下:
- 9、分别求100以内所有偶数之和,以及所有奇数之和。
- 10、计算当前系统上的所有用的id之和。
- 11、通过脚本参数传递一个目录给脚本,而后计算此目录下所有文本文件的行数之和;并说明此类文件的总数。
- 12、计算/etc/passwd文件中的第10个用户和第20个用户的id号之和。
- 13、计算/etc/rc.d/init.d/functions和/etc/inittab文件的空白行数之和。
- 14、编写一个脚本,找出172.16.141.X网络中哪些主机地址被使用,哪些未被使用,并把结果保存至相应的文件中。
- 15、写一个脚本,实现:能探测C类、B类或A类网络中的所有主机是否在线。
- 16、编写脚本,通过命令行参数传入一个用户名,判断ID是偶数还是奇数。
- 17、分别用while、for循环检测10.0.0.1/24网段存活的IP地址
脚本编程详解
编程语言的分类:根据运行方式
1、编译运行:源代码 --> 编译器 (编译)--> 程序文件
2、解释运行:源代码 --> 运行时启动解释器,由解释器边解释边运行
根据其编程过程中功能的实现是调用库还是调用外部的程序文件:
1、shell脚本编程:利用系统上的命令及编程组件进行编程
2、完整编程:利用库或编程组件进行编程
编程模型:过程式编程语言,面向对象的编程语言
程序=指令+数据
1、过程式:以指令为中心来组织代码,数据是服务于代码;
顺序执行
选择执行
循环执行
代表:C,bash
2、对象式:以数据为中心来组织代码,围绕数据来组织指令;
类(class):实例化对象,method;
代表:Java, C++, Python
名词解释
变量:
1、局部变量
2、本地变量
3、环境变量
4、位置参数变量
5、特殊变量具体参考:
https://blog.csdn.net/weixin_44983653/article/details/95232625
- 位置参数变量
位置参数变量 :主要是向脚本传递参数。# myscript.shargu1 argu2引用方式:
argu1 argu2
$1,$2, ..., ${10},${11}, ...轮替:
shift[n]:位置参数轮替示例:
root@LeeMumu:~# cat echo.sh# 通过此脚本,了解位置参数变量
#!/bin/bashecho $1
echo $2root@LeeMumu:~# ./echo.sh "The line 1." "The line 2."
The line 1.
The line 2.
- 特殊变量
$0:脚本文件路径本身
$#:脚本参数的个数
$*:所有参数
$@:所有参数
- 算术运算和赋值
常用的算术运算符号:
1、+加
2、-减
3、*乘
4、/除
5、**次方
6、%余数
算术运算格式:
1、letVAR=算术运算表达式
2、VAR=$[算术运算表达式]
3、VAR=$((算术运算表达式))
# 给变量空间赋值时一定要使用 $[ ] 或者 $(( ))
4、VAR=$(expr $ARG1 $OP $ARG2)
# (): 括号内部是运行命令,直接取命令运行结果# 注意:乘法符号在有些场景中需要使用转义符。增强型赋值:
变量做某种算术运算后回存至此变量中,如下两种赋值方式表示同一个意思:
let i=$i+#
let i+=#
常用的增强型赋值:
+=,-=,*=, /=, %=
自增:
VAR=$[$VAR+1]
# 前面的 VAR 是变量空间,后面的 $VAR 是直接取变量空间里的值,注意区分
letVAR+=1
letVAR++ 自减:
VAR=$[$VAR-1]
letVAR-=1
letVAR--
%(余数) 示例:
root@LeeMumu:~# yushu=$((9%2))
root@LeeMumu:~# echo $yushu
1
root@LeeMumu:~# yushu=$((8%2))
root@LeeMumu:~# echo $yushu
0
shell 脚本
1、什么是 shell 脚本?
1、shell 脚本是过程式编程,解释运行,依赖于外部程序文件运行。
2、shell 脚本是命令的堆积。
# 很多命令不具有幂等性,需要用程序逻辑来判断运行条件是否满足,以避免其运行中发生错误。2、如何编写 shell 脚本?
脚本文件的第一行,顶格位置需要给出:
shebang,解释器路径,用于指明解释执行当前脚本的解释器程序文件。
常见的解释器:
#!/bin/bash
#!/usr/bin/python
#!/usr/bin/perl
同时,在脚本顶部还可以加入版本、作者和描述等信息,如下:
#!/bin/bash
# Version: 0.0.1
# Author: LeeMumu
# Description: XXX3、如何运行 shell 脚本?
(1) 赋予执行权限,并直接运行此程序文件
chmod +x /PATH/TO/SCRIPT_FILE
source /PATH/TO/SCRIPT_FILE
(2) 直接运行解释器,将脚本以命令行参数传递给解释器程序
bash /PATH/TO/SCRIPT_FILE4、shell 脚本注意事项:
(1) 脚本中的空白行会被解释器忽略
(2) 脚本中,除了shebang,余下所有以#开头的行,都会被视作注释行而被忽略;此即为注释行
(3) shell 脚本的运行是通过运行一个子shell进程实现的
脚本中的条件测试
条件测试:判断某需求是否满足,需要由测试机制来实现。如何编写测试表达式以实现所需的测试:
(1) 执行命令,并利用命令状态返回值来判断;
0:成功
1-255:失败
(2) 测试表达式
testEXPRESSION
[ EXPRESSION ]
[[ EXPRESSION ]]# 注意:EXPRESSION两端必须有空白字符,否则为语法错误。
bash 测试分类
bash 的测试类型:
1、数值测试
2、字符串测试
3、文件测试
4、组合条件测试
- 1、数值测试
数值测试:数值比较
-eq:是否等于
# [ $num1 -eq $num2 ],注意空格
-ne:是否不等于
-gt:是否大于
-ge:是否大于等于
-lt:是否小于
-le:是否小于等于
示例:
root@LeeMumu:~# [ 2 -eq 2 ]# 命令执行成功
root@LeeMumu:~# echo $?
0
root@LeeMumu:~# [ 2 -gt 2 ]# 命令执行失败
root@LeeMumu:~# echo $?
1
- 2、字符串测试
字符串测试:
==:是否等于
# [ STRING1 == STRING2 ],注意空格
> :是否大于
< :是否小于
!=:是否不等于
=~:左侧字符串是否能够被右侧的PATTERN所匹配 -z "STRING":判断指定的字串是否为空;空则为真,不空则假
# [[ -z “STRING” ]]
-n "STRING":判断指定的字符串是否不空;不空则真,空则为假
# 注意:
(1) 字符串要加引用
(2) 要使用 [[ ]]
示例:
root@LeeMumu:~# [ a == b ]# 命令执行失败
root@LeeMumu:~# echo $?
1
root@LeeMumu:~# [ aba == baa ]# 命令执行失败
root@LeeMumu:~# echo $?
1
root@LeeMumu:~# [ a == a ]# 命令执行成功
root@LeeMumu:~# echo $?
0
root@LeeMumu:~# [[ -z "" ]]# 命令执行成功,字符串为空则为真
root@LeeMumu:~# echo $?
0
root@LeeMumu:~# [[ -z "aaa" ]]# 命令执行失败,字符串非空则为假
root@LeeMumu:~# echo $?
1
- 3、文件测试
文件测试:
1、存在性测试
-aFILE
-eFILE
文件的存在性测试,存在则为真,否则则为假2、存在性及类型测试
-bFILE:是否存在并且为 块设备文件
-cFILE:是否存在并且为 字符设备文件
-dFILE:是否存在并且为 目录文件
-fFILE:是否存在并且为 普通文件
-hFILE:是否存在并且为 符号链接文件
-LFILE:是否存在并且为 符号链接文件
-pFILE:是否存在且为 命名管道文件
-SFILE:是否存在且为 套接字文件3、文件权限测试:
-rFILE:是否存在并且 对当前用户可读
-wFILE:是否存在并且 对当前用户可写
-xFILE:是否存在并且 对当前用户可执行4、特殊权限测试:
-uFILE:是否存在并且 拥有suid权限
-gFILE:是否存在并且 拥有sgid权限
-kFILE:是否存在并且 拥有sticky权限5、文件是否有内容:
-sFILE:是否有内容,有内容为真,没内容为假6、时间戳:
-NFILE:文件自从上一次读操作后是否被修改过7、从属关系测试:
-OFILE:当前用户是否为文件的属主
-GFILE:当前用户是否属于文件的属组8、双目测试:
FILE1-efFILE2:FILE1与FILE2是否指向同一个文件系统的相同inode的硬链接;
FILE1-ntFILE2:FILE1是否新于FILE2,新为真,否则为假
FILE1-otFILE2:FILE1是否旧于FILE2,旧为真,否则为假
示例:
root@LeeMumu:~# touch space.txt# 创建空文件
root@LeeMumu:~# cat space.txt
root@LeeMumu:~# [[ -s space.txt ]]# 有内容为真,没内容为假
root@LeeMumu:~# echo $?
1
root@LeeMumu:~# echo 1 > space.txt
root@LeeMumu:~# [[ -s space.txt ]]
root@LeeMumu:~# echo $?
0
root@LeeMumu:~# [[ -e space.backup.txt ]]# 存在为真,不存在为假
root@LeeMumu:~# echo $?
1
root@LeeMumu:~# touch space.backup.txt
root@LeeMumu:~# [[ -e space.backup.txt ]]
root@LeeMumu:~# echo $?
0
- 4、组合条件测试
逻辑运算:
第一种方式:
1、与运算:COMMAND1 && COMMAND2
# && 前面为真时, && 后面就继续执行
# && 前面为假时, && 后面就不执行
2、或运算:COMMAND1 || COMMAND2
# 常用于判断此用户是否存在,如果不存在就对用户进行添加。
# id user1 &> /dev/null || useradd user1
# || 前面为真时, || 后面就不执行
# || 前面为假时, || 后面就继续执行
3、非运算:! COMMAND 例如:
# [ -O FILE ] && [ -r FILE ]第二种方式:
1、与运算:EXPRESSION1-aEXPRESSION2
2、或运算:EXPRESSION1-oEXPRESSION2
3、非运算:! EXPRESSION 例如:
# [ -O FILE -a -x FILE ]
示例:
root@LeeMumu:~# [ 1 -eq 2 ] && echo 2
root@LeeMumu:~# [ 1 -lt 2 ] && echo 2
2
root@LeeMumu:~# [ 1 -eq 2 ] || echo 2
2
root@LeeMumu:~# [ 1 -lt 2 ] || echo 2
脚本的状态返回值
脚本的状态返回值:默认是脚本中执行的最后一条件命令的状态返回值。可用如下命令自定义状态退出状态码
# exit [n]:n为指定的状态码,一般制定为 1~255 结束脚本执行。注意:shell进程遇到exit时,即会终止,因此,整个脚本执行即为结束。
脚本语法检测和调试执行
1、检测脚本中的语法错误:
# bash -n /path/to/some_script2、对脚本进行调试执行:
# bash -x /path/to/some_script
编程脚本之用户交互 用户交互时,会使用到 read 命令。
该命令是从键盘读取变量的值,通常用在shell脚本中与用户进行交互的场合。该命令可以一次读取多个变量的值,变量和输入的值都需要使用空格隔开。
注意:在用户交互过程中,如果对输入的内容进行删除,需要同时使用
Ctrl + Delete
组合键。read:从键盘读取变量值使用格式:
read[option]... [name ...]
-p 'PROMPT'# 指定读取值时的提示符
-t TIMEOUT# 指定读取值时等待的时间(秒)
示例:
root@LeeMumu:~# cat read.sh
#!/bin/bash
#
read -p "Please input what you want:" aBa# 输入的信息赋值给了变量 aBa
echo "You input the $aBa!"
root@LeeMumu:~# ./read.sh
Please input what you want:This is a new line
You input the This is a new line!
脚本执行方式 shell 脚本是过程式编程语言,代码的执行顺序分为:
1、顺序执行
# 逐条运行脚本代码
2、选择执行
# 代码有一个分支:条件满足时才会执行
# 两个或以上的分支:只会执行其中一个满足条件的分支
3、循环执行
# 代码片断(循环体)要执行0、1或多个来回
1、选择执行 if 语句
单分支的if语句 格式:
if测试条件
then
代码分支
fi
双分支的if语句 格式:
if测试条件;
then
条件为真时执行的分支
else
条件为假时执行的分支
fi
多分支的if语句
ifCONDITION1;
then
条件1为真 分支
elifCONDITION2;
then
条件2为真 分支
elifCONDITION3;
then
条件3为真 分支
... ...
elifCONDITIONn;
then
条件n为真 分支
else
所有条件均不满足时的分支
fi注意:即便多个条件可能同时都能满足,分支只会执行中其中一个,首先测试为“真”的条件。
case 语句
语法格式:
case$VARAIBLEin
PAT1)
分支1
;
;
PAT2)
分支2
;
;
...
*)
分支n
;
;
esac
对如上 case 语法格式进行说明:
# case关键字
# in关键字
# PAT1)仅支持 glob 风格的通配符号
# VARDIBLE变量
# *)相当于 else
# esac结束关键字(与 case 相反)
# ;
;
双分号
# 适用于变量值同多个字符串进行等值或不等值比较的情形,仅能替代部分多分支 if 语句
# case 支持 glob 风格的通配符
*# 任意长度的任意字符;
?# 任意单个字符;
[]# 范围内任意单个字符;
a|b# a或b
示例:写一个服务框架脚本。要求如下:
$lockfile,值/var/lock/subsys/SCRIPT_NAME(1) 此脚本可接受start, stop, restart, status四个参数之一;
(2) 如果参数非此四者,则提示使用帮助后退出;
(3) start,则创建lockfile,并显示启动;
stop,则删除lockfile,并显示停止;
restart,则先删除此文件再创建此文件,而后显示重启完成;
status,如果lockfile存在,则显示running,否则,则显示为stopped。
脚本如下:
#!/bin/bash
#
# chkconfig: - 50 50
# description: test service script
#
prog=$(basename $0)
lockfile=/var/lock/subsys/$progcase $1in
start)
if [ -f $lockfile ];
then
echo "$prog is running yet."
else
touch $lockfile
[ $? -eq 0 ] && echo "start $prog finshed."
fi
;
;
stop)
if [ -f $lockfile ];
then
rm -f $lockfile
[ $? -eq 0 ] && echo "stop $prog finished."
else
echo "$prog is not running."
fi
;
;
restart)
if [ -f $lockfile ];
then
rm -f $lockfile
touch $lockfile
echo "restart $prog finished."
else
touch -f $lockfile
echo "start $prog finished."
fi
;
;
status)
if [ -f $lockfile ];
then
echo "$prog is running"
else
echo "$prog is stopped."
fi
;
;
*)
echo "Usage: $prog {start|stop|restart|status}"
exit 1
esac
命令执行:
# cp testservice /etc/init.d/
# chkconfig --add testservice
# chkconfig --list testservice
# service testservice start
# ls /var/lock/subsys/# 启动服务后都会在这个目录下进行文件创建
2、循环执行
循环执行:是指将一段代码重复执行0、1或多次。
进入条件:条件满足时才进入循环。
退出条件:每个循环都应该有退出条件,以有机会退出循环。
循环分为三种:
1、for循环
2、while循环
3、until循环
进入条件:
for:列表元素非空
while:条件测试结果为“真”
unitl:条件测试结果为“假”
退出条件:
for:列表元素遍历完成
while:条件测试结果为“假”
until:条件测试结果为“真”
循环控制语句:
# continue:提前结束本轮循环,不会执行后面的命令,直接进入下一轮循环判断。
whileCONDITION1;
do
CMD1
...
ifCONDITION2;
then
continue
fi
CMDn
...
done# break:提前跳出循环
whileCONDITION1;
do
CMD1
...
ifCONDITION2;
then
break
fi
done
创建死循环:
while true;
do
循环体
done
退出方式:
某个测试条件满足时,让循环体执行break命令。
示例:求100以内所有偶数之和;
#!/bin/bash
#
declare -i evensum=0
declare -i i=0while [ $i -le 100 ];
do
let i++
if [ $[$i%2] -eq 1 ];
then
continue
fi
let evensum+=$i
doneecho "Even sum: $evensum"
示例:求100以内所奇数之和
#!/bin/bash
#
declare -i oddsum=0
declare -i i=1while true;
do
let oddsum+=$i
let i+=2
if [ $i -gt 100 ];
then
break
fi
done
sleep 命令说明:
sleep 命令:
- delay for a specified amount of time
命令格式:
# sleep NUMBER
sleep 示例:每隔3秒钟到系统上获取已经登录用户的用户的信息;其中,如果logstash用户登录了系统,则记录于日志中,并退出。
#!/bin/bash
#
while true;
do
if who | grep "^logstash\>" &> /dev/null;
then
break
fi
sleep 3
doneecho "$(date +"%F %T") logstash logged on" >> /tmp/users.log #!/bin/bash
#
until who | grep "^logstash\>" &> /dev/null;
do
sleep 3
doneecho "$(date +"%F %T") logstash logged on" >> /tmp/users.log
2.1 for 循环
for 循环包括以下两种
1、遍历列表
2、控制变量
遍历列表:语法格式:
forVARAIBLEinLIST;
do
循环体
done参数解释:
1、for 是 关键字
2、VARAIBLE 是 变量
3、in 是 关健字
4、LIST 是 赋值列表
5、do 和 done 是 关键字VARAIBLE 赋值的三种形式:
1、VARAIBLE = VALUE
2、read 语句
3、for 语句进入和退出条件:
1、进入条件:只要列表有元素,即可进入循环
2、退出条件:列表中的元素遍历完成
LIST 列表的生成方式 一般有如下五种:
- 1、直接给出
root@LeeMumu:~# echo 1 2 3 4 5
1 2 3 4 5
- 2、整数列表
(1)、{start..end}
root@LeeMumu:~# echo {1..5}
1 2 3 4 5(2)、seq [start[incremtal]]last# 中间参数是 步长
root@LeeMumu:~# seq 1 3
1
2
3
root@LeeMumu:~# seq 3
1
2
3
root@LeeMumu:~# seq 3 3 9
3
6
9
- 3、返回列表参数
ls:返回列表 一行一个
cat:查看文件的返回列表参数# 只要结果能输出字串的
- 4、glob
匹配符合条件的列表:
# ls -d /etc/p*
- 5、变量引用
$@ :参数传递
$* :参数传递
root@LeeMumu:~# passwd_Lines=`wc -l /etc/passwd | cut -d' ' -f1`
# 注意:以上命令是 反引号,作命令引用
root@LeeMumu:~# echo $passwd_Lines
33
root@LeeMumu:~# seq 1 $passwd_Lines
1
2
...
32
33
root@LeeMumu:~#echo {1.."$passwd_Lines"}
{1..33}
# 注意:使用花括号时引用变量时,不会生效,可用 seq
root@LeeMumu:~# echo {1..$passwd_Lines}
{1..33}
root@LeeMumu:~# echo {1..33}
1 2 3 4 5 6 ... ...32 33
root@LeeMumu:~# echo '$passwd_Lines'
$passwd_Lines
for 循环 示例 1、求 100 以内的正整数之和。
#!/bin/bash
#
declare -i sum=0for i in {1..100};
do
echo "\$sum is $sum, \$i is $i"
sum=$[$sum+$i]
doneecho $sum
2、判断/var/log目录下的每一个文件的内容类型。
#!/bin/bash
#
for filename in /var/log/*;
do
if [ -f $filename ];
then
echo "Common file."
elif [ -d $filename ];
then
echo "Directory."
elif [ -L $filename ];
then
echo "Symbolic link."
elif [ -b $filename ];
then
echo "block special file."
elif [ -c $filename ];
then
echo "character special file."
elif [ -S $filename ];
then
echo "Socket file."
else
echo "Unkown."
fi
done
3、打印 九九乘法表
#外循环控制乘数,内循环控制被乘数;
#!/bin/bash
#
for j in {1..9};
do
for i in $(seq 1 $j);
do
echo -n -e "${i}X${j}=$[${i}*${j}]\t"
done
echo
done
for 循环的特殊用法
语法格式;
for((控制变量初始化;
条件判断表达式;
控制变量的修正语句));
do
循环体
done控制变量初始化:仅在循环代码开始运行时执行一次
控制变量的修正语句:每轮循环结束会先进行控制变量修正运算,而后再做条件判断
示例:求100以内所有正整数之和
#!/bin/bash
#
declare -i sum=0for ((i=1;
i<=100;
i++));
do
let sum+=$i
doneecho "Sum: $sum."示例:打印九九乘法表
#!/bin/bash
#
for ((j=1;
j<=9;
j++));
do
for ((i=1;
i<=j;
i++));
do
echo -e -n "${i}X${j}=$[${i}*${j}]\t"
done
echo
done
2.2 while 循环
语法格式:
whileCONDITION;
do
循环体
循环控制变量修正表达式
done进入条件:CONDITION测试为 真
退出条件:CONDITION测试为 假
示例:求100以内的正整数之和
#!/bin/bash
#
declare -i sum=0
declare -i i=1while [ $i -le 100 ];
do
let sum+=$i
let i++
doneecho $sum
- while 循环的特殊用法(遍历文件的行):
whilereadVARIABLE;
do
循环体;
done
示例:找出ID号为偶数的用户,显示其用户名、ID及默认shell
#!/bin/bash
#
while read line;
do
userid=$(echo $line | cut -d: -f3)
username=$(echo $line | cut -d: -f1)
usershell=$(echo $line | cut -d: -f7) if [ $[$userid%2] -eq 0 ];
then
echo "$username, $userid, $usershell."
fi
done < /etc/passwd
2.3 until 循环
untilCONDITION;
do
循环体
循环控制变量修正表达式
done进入条件:CONDITION测试为 假
退出条件:CONDITION测试为 真
示例:求100以内的正整数之和
#!/bin/bash
#
declare -i sum=0
declare -i i=1until [ $i -gt 100 ];
do
let sum+=$i
let i++
doneecho $sum
脚本示例 1、vim 如何定制自动缩进四个字符。
vim 的配置文件是:/etc/vimrc
可以对此配置文件进行编辑,添加配置: set tabstop=4 ,重读配置,使文件生效即可。如下:
[root@LeeMumu ~]# vi /etc/vimrc# 编辑 vim 的配置文件
set tabstop=4
[root@LeeMumu ~]# source /etc/vimrc# 重读配置文件。使文件生效
2、实现自动添加三个用户,并计算这三个用户的 uid 之和。
[root@LeeMumu ~]# ./sUMID.sh
Add user user21 successfully.
The user user21 ID is:1004.
Add user user22 successfully.
The user user22 ID is:1005.
Add user user33 successfully.
The user user33 ID is:1006.
The sum of these UserID is:3015.
[root@LeeMumu ~]# tail -n 3 /etc/passwd
user21:x:1004:1017::/home/user21:/bin/bash
user22:x:1005:1018::/home/user22:/bin/bash
user33:x:1006:1019::/home/user33:/bin/bash
[root@LeeMumu ~]# cat sUMID.sh
#!/bin/bash
#
declare -i sum=0for i in user21 user22 user33;
do
if id $i &> /dev/null ;
then
echo "The user $i exists."
else
useradd $i
echo "Add user $i successfully."
fi
ID=`grep "^$i" /etc/passwd | cut -d":" -f3`
#ID=$(grep "^$i" /etc/passwd | cut -d":" -f3)# 用 $() 或 `` 都可以
echo "The user $i ID is:$ID. "
sum=$[$sum+$ID]
done echo "The sum of these UserID is:$sum."
3、通过命令传递两个文本文件路径给脚本,计算其空白行数之和。
#!/bin/bash
#
file1_lines=$(grep "^$" $1 | wc -l)
file2_lines=$(grep "^$" $2 | wc -l)echo "Total blank lines: $[$file1_lines+$file2_lines]"
4、通过参数传递一个用户名给脚本,此用户不存时,则添加之。
第一种:
#!/bin/bash
#
if ! grep "^$1\>" /etc/passwd &> /dev/null;
then
useradd $1
echo $1 | passwd --stdin $1 &> /dev/null
echo "Add user $1 finished."
fi 第二种:
#!/bin/bash
#
if [ $# -lt 1 ];
then
echo "At least one username."
exit 2
fiif ! grep "^$1\>" /etc/passwd &> /dev/null;
then
useradd $1
echo $1 | passwd --stdin $1 &> /dev/null
echo "Add user $1 finished."
fi第三种:
#!/bin/bash
#
if [ $# -lt 1 ];
then
echo "At least one username."
exit 2
fiif grep "^$1\>" /etc/passwd &> /dev/null;
then
echo "User $1 exists."
else
useradd $1
echo $1 | passwd --stdin $1 &> /dev/null
echo "Add user $1 finished."
fi
5、通过命令行参数给定两个数字,输出其中较大的数值。
第一种:
#!/bin/bash
#
if [ $# -lt 2 ];
then
echo "Two integers."
exit 2
fiif [ $1 -ge $2 ];
then
echo "Max number: $1."
else
echo "Max number: $2."
fi第二种:(相对于第一种来说,第二种是代码优化)
#!/bin/bash
#
if [ $# -lt 2 ];
then
echo "Two integers."
exit 2
fideclare -i max=$1if [ $1 -lt $2 ];
then
max=$2
fiecho "Max number: $max."第三种:(if 语句可嵌套)
#!/bin/bash
#
if [ $# -lt 2 ];
then
echo "TWO INTEGERS!"
exit 1
else
if [ $1 -lt $2 ];
then
echo "The $2 is bigger than $1."
elif [ $1 -eq $2 ];
then
echo "The $1 is equal than $1."
else
echo "The $1 is bigger than $1."
fi
fi
6、脚本参数传递一个文件路径给脚本,判断此文件的类型。
#!/bin/bash
#
if [ $# -lt 1 ];
then
echo "At least on path."
exit 1
fiif ! [ -e $1 ];
then
echo "No such file."
exit 2
fiif [ -f $1 ];
then
echo "Common file."
elif [ -d $1 ];
then
echo "Directory."
elif [ -L $1 ];
then
echo "Symbolic link."
elif [ -b $1 ];
then
echo "block special file."
elif [ -c $1 ];
then
echo "character special file."
elif [ -S $1 ];
then
echo "Socket file."
else
echo "Unkown."
fi
7、传递一个参数给脚本,此参数为用户名;根据其ID号来判断用户类型。 (0: 管理员;1-999:系统用户;1000+:登录用户)
#!/bin/bash
#
[ $# -lt 1 ] && echo "At least on user name." && exit 1! id $1 &> /dev/null && echo "No such user." && exit 2userid=$(id -u $1)if [ $userid -eq 0 ];
then
echo "root"
elif [ $userid -ge 1000 ];
then
echo "login user."
else
echo "System user."
fi
8、写一个脚本,要求如下:
(1) 列出如下菜单给用户:
disk) show disks info;
mem) show memory info;
cpu) show cpu info;
*) quit;
(2) 提示用户给出自己的选择,而后显示对应其选择的相应系统信息。
#!/bin/bash
#
cat << EOF
cpu) display cpu information
mem) display memory infomation
disk) display disks information
quit) quit
===============================
EOFread -p "Enter your option: " optionwhile [ "$option" != "cpu" -a "$option" != "mem" -a "$option" != "disk" -a "$option" != "quit" ];
do
echo "cpu, mem, disk, quit"
read -p "Enter your option again: " option
doneif [ "$option" == "cpu" ];
then
lscpu
elif [ "$option" == "mem" ];
then
free -m
elif [ "$option" == "disk" ];
then
fdisk -l /dev/[hs]d[a-z]
else
echo "quit"
exit 0
fi
9、分别求100以内所有偶数之和,以及所有奇数之和。
第一个脚本:
#!/bin/bash
#计算100以内所有奇数的和以及所有偶数的和;分别显示之
#奇数和变量
let SUM1=0
#偶数和变量
let SUM2=0
for I in {1..100};
do
if [ $[$I%2] -eq 0 ];
then
SUM1=$[$SUM1+$I]
else
SUM2=$[$SUM2+$I]
fi
doneecho -e "SUM1=$SUM1\nSUM2=$SUM2"第二个脚本:
#!/bin/bash
#
declare -i even=0
declare -i odd=0for i in {1..100};
do
if [ $[$i%2] -eq 0 ];
then
even=$[$even+$i]
else
odd=$[$odd+$i]
fi
doneecho "The sum of the even_number between 1 and 100 is: $even"
echo "The sum of the odd_number between 1 and 100 is: $odd"
echo "The sum of the integer between 1 and 100 is: $[$even+$odd]"
10、计算当前系统上的所有用的id之和。
#!/bin/bash
#declare -i passwd_Lines=`wc -l /etc/passwd | cut -d' ' -f1`
declare -i sum_UID=0for i in `cat /etc/passwd | cut -d':' -f3`;
do
sum_UID=$[$sum_UID+$i]
doneecho "The sum of the user-ID is:$sum_UID"
11、通过脚本参数传递一个目录给脚本,而后计算此目录下所有文本文件的行数之和;并说明此类文件的总数。
#!/bin/bash
#declare -i count=0
declare -i line_count=0if [ $# -eq 1 ];
then
if [ -d $1 ];
then
for filename in $1* ;
do
if [ -f $filename ];
then
line_count=$[$line_count+`wc -l $filename | cut -d' ' -f1`]
count=$[$count+1]
echo "The Common_File $filename has $line_count lines."
else
exit 1
fi
done
else
echo -e "Please Input Correct Directory.\nFor Example: /path/path/"
exit 2
fi
else
echo "Please Input One Directory!"
exit 3
fi
echo " "
echo "The Number of Common_File is:$count"
echo "The Total Lines of Common_File is:$line_count"
12、计算/etc/passwd文件中的第10个用户和第20个用户的id号之和。
[root@LeeMumu ~]# bash sum1020.sh
The UID OF the tenth user is: 11.
The UID OF the twentith user is: 59.
The UID_SUM OF the tenth user and the twentith user is: 70.
[root@LeeMumu ~]# cat sum1020.sh
#!/bin/bash
#
ID10=$(head -10 /etc/passwd | tail -1 | cut -d":" -f3)
ID20=$(head -20 /etc/passwd | tail -1 | cut -d":" -f3)sum1020=$[$ID10+$ID20]echo "The UID OF the tenth user is: $ID10."
echo "The UID OF the twentith user is: $ID20."
echo "The UID_SUM OF the tenth user and the twentith user is: $sum1020."
13、计算/etc/rc.d/init.d/functions和/etc/inittab文件的空白行数之和。
[root@LeeMumu ~]# bash sumSPACElines.sh
The /etc/rc.d/init.d/functions has 91 space-lines.
The /etc/inittab has 0 space-lines.
The /etc/rc.d/init.d/functions and /etc/inittab totally have 91 space-lines.
[root@LeeMumu ~]# cat sumSPACElines.sh
#!/bin/bash
#
ID10=$(grep "^[[:space:]]*$"/etc/rc.d/init.d/functions | wc -l)
ID20=$(grep "^[[:space:]]*$"/etc/inittab | wc -l)sum1020=$[$ID10+$ID20]echo "The /etc/rc.d/init.d/functions has $ID10 space-lines."
echo "The /etc/inittab has $ID20 space-lines."
echo "The /etc/rc.d/init.d/functions and /etc/inittab totally have $sum1020 space-lines."
14、编写一个脚本,找出172.16.141.X网络中哪些主机地址被使用,哪些未被使用,并把结果保存至相应的文件中。
[root@LEEMUMU ~]# cat ping.sh
#!/bin/bash
#declare -i upnum=0
declare -i downnum=0
declare -i i=1pinghost() {
if ping $1 -c 1 -W 1 &>/dev/null;
then
echo -e "\033[1;
32m$1 is up.\033[0m"| tee -a up20190717.txt
upnum=$[$upnum+1]
else
echo -e "\033[1;
31m$1 is down.\033[0m"| tee -a down20190717.txt
downnum=$[$downnum+1]
fi
}while [ $i -le 254 ];
do
pinghost 172.16.141.$i
let i++
doneecho "Uphost is $upnum."
echo "Downhost is $downnum."
15、写一个脚本,实现:能探测C类、B类或A类网络中的所有主机是否在线。
#!/bin/bash
#cping() {
local i=1
while [ $i -le 5 ];
do
if ping -W 1 -c 1 $1.$i &> /dev/null;
then
echo "$1.$i is up"
else
echo "$1.$i is down."
fi
let i++
done
}bping() {
local j=0
while [ $j -le 5 ];
do
cping $1.$j
let j++
done
}aping() {
local x=0
while [ $x -le 255 ];
do
bping $1.$x
let x++
done
}
16、编写脚本,通过命令行参数传入一个用户名,判断ID是偶数还是奇数。
[root@LeeMumu ~]# ./evenorodd.sh
Please Input One UserName:JC9
The UserID Of JC9 is even!
[root@LeeMumu ~]# ./evenorodd.sh
Please Input One UserName:jc8
The jc8 Not Exist!
Please Input Another UserName!
[root@LeeMumu ~]# ./evenorodd.sh
Please Input One UserName:JC6
The UserID Of JC6 is odd!
[root@LeeMumu ~]# cat evenorodd.sh
#!/bin/bash
#
read -p "Please Input One UserName:" UserNameif ! id $UserName &> /dev/null;
then
echo -e "\e[1;
31mThe $UserName Not Exist!\e[0m"
echo -e "\e[1;
32mPlease Input Another UserName!\e[0m"
exit 1
else
if [ $[`id -u $UserName`%2] -eq 0 ];
then
echo -e "\e[1;
33mThe UserID Of $UserName is even!\e[0m"
else
echo -e "\e[1;
34mThe UserID Of $UserName is odd!\e[0m"
fi
fi
17、分别用while、for循环检测10.0.0.1/24网段存活的IP地址 第一种:
#!/bin/bash
# 先定义函数,再引用函数
while_ping(){
local i=1
while [ $i -le 255 ];
do
ping -W 1 -c 1 $1.$i &> /dev/null
if [ $? == 0 ];
then
echo "$1.$i is up"
else
echo "$1.$i is down"
fi
let i++
done
}########################################################for_ping(){for i in {1..255};
do
ping -W 1 -c 1 $1.$i &> /dev/null
if [ $? == 0 ];
then
echo "$1.$i is up"
else
echo "$1.$i is down"
fi
done
}########################################################if [ $# -lt 2 ];
then
echo "Usage sh $0 {for_ping|while_ping} Network"
echo "Such as :for_ping 192.168.1 OR while_ping 192.168.1"
exit 1
elif [[ $1 == "for_ping" ]];
then
echo "for_ping"
for_ping $2
elif [[ $1 == "while_ping" ]];
then
echo "while_ping"
while_ping $2
fi
第二种:
#!/bin/bash
for ip in {1..255};do
ping -c 1 10.0.0.$ip > /dev/null 2>&1
if [ $? -eq 0 ];
then
echo 10.0.0.$ip is UP
else
echo 10.0.0.$ip is DOWN
fi
done##############################################declare -i ip=1
while [ $ip -le 255 ];
do
ping -c 1 10.0.0.$ip > /dev/null 2>&1
if [ $? -eq 0 ];
then
echo 10.0.0.$ip UP
else
echo 10.0.0.$ip DOWN
fi
let ip++
done
推荐阅读
- Shell-Bash变量与运算符
- Linux下面如何查看tomcat已经使用多少线程
- Beego打包部署到Linux
- 「按键精灵安卓版」关于全分辨率脚本的一些理解(非游戏app)
- Linux|109 个实用 shell 脚本
- linux定时任务contab
- 芯灵思SinlinxA33开发板Linux内核定时器编程
- day16-Linux|day16-Linux 软件管理
- 如何在阿里云linux上部署java项目
- Xshell5|Xshell5 远程连接本地虚拟机Ubuntu16