练习一
选择
1、函数内如何设置局部变量 (A)
- A:
local
- B:
export
- C:
source
- D:
function
2、以下哪一种指令显示的结果为 $test
(C)
- A:
\echo $test
- B:
echo "$test"
- C:
echo '$test'
- D:
echo "${test}"
3、一个 bash shell 脚本的第 1 行是什么 (A)
- A:
#!/bin/bash
- B:
#/bin/bash
- C:
#/bin/csh
- D:
/bin/bash
4、以下参数,如何在执中查看执行过程 (A)
- A:
-x
- B:
-X
- C:
-s
- D:
-S
简答
1、如何显示默认的环境变量
使用 printenv
或 env
命令。
2、如何设置环境变量与局部变量
在 /etc/profile
、/etc/bashrc
、~/.bash_profile
、~/.bashrc
下使用 export
命令导出的变量为环境变量,在函数块中使用 local
定义的变量为局部变量。
编程
1、按照时间生成文件 2018-05-22.log
将每天的磁盘使用状态写入到对应日期的文件
$ df -h | awk 'NR==2{print "总容量: "$2,"\n已使用:"$3,"\n剩余可用:"$4,"\n使用率:"$5}' > `date +%F`.log
2、统计Nginx日志中每个IP的访问量有多少,日志如下:
192.168.56.1 - - [21/May/2018:20:44:06 -0400] "GET /index.html HTTP/1.0" 404 169 "-" "ApacheBench/2.3" "-"/code/index.html
$ cat access.log | awk '{print $1}' | sort | uniq -c | sort -nr
3、写一个脚本计算一下 Linux 系统所有进程占用内存大小的和。
$ ps -e -o 'rss' | awk '{total+=$1}END{print total/1024"M"}'
109.605M
5、在 /backup
下创建 10 个 .txt
的文件,找到 /backup
目录下所有后缀名为 .txt
的文件
- 批量修改
txt
为txt.bak
- 把所有的
.bak
文件打包压缩为123.tar.gz
- 批量还原文件的名字,及把增加的
.bak
再删除
#!/bin/bash
ls /backup/*.txt | xargs -n1 | xargs -i mv {} {}.bak
tar zPcf 123.tar.gz /backup/*.bak
for file_name in `ls /backup/*.bak`;do
mv ${file_name} ${file_name%.*}
done
练习二
填空
1、写出以下位置参数的作用
$0
:脚本名称$n
:第 n 个参数值$#
:参数个数$*
:所有参数,当外层使用""
时当做一整个字符串处理$@
:所有参数,当外层使用""
时每个参数作为一个单独的字符串
2、写出以下特殊变量的作用
$?
:上一条命令的退出状态码$$
:当前脚本进程号$!
:上一个后台运行的进程的进程号$_
:命令指定的最后一个参数
3、写出以下字母比较符的作用
-eq
:相等-ne
:不相等-gt
:大于-ge
:大于等于-lt
:小于-le
:小于等于
4、写出下面特殊变量扩展的意义
${oldboy}
:输出变量oldboy
的值${#oldboy}
:输出变量oldboy
的值的长度${url#*.}
:自左向右删除字符串开头到第一次出现.
的位置${url##*.}
:自左向右删除字符串开头至最后一次出现.
字符之间的所有字符${url%.*}
:自右向左删除字符串尾部到第一次出现.
的位置${url%%.*}
:自右向左删除字符串尾部到最后一次出现.
的位置
简答
1、写出 3 个以上可用于计算的命令
expr
bc
let
编程
1、输入两个整数计算这两个整数的相加,相减,相乘,相除,求余的结果
#!/bin/bash
read -p 'input num1: ' num1
read -p 'input num2: ' num2
echo "$num1 + $num2 = $[ num1 + num2] "
echo "$num1 - $num2 = $[ num1 - num2] "
echo "$num1 * $num2 = $[ num1 * num2] "
echo "$num1 / $num2 = $[ num1 / num2] "
2、把一个文本文档的前五行中包含字母的行删除掉,同时把 6 到 10 行中的全部字母删除掉
$ sed -r '1,5{/[a-z]+/d};6,10{s/[a-z]//g}' text.txt
3、打印下面这句话中字母数小于 5 的单词
I am lizhenya teacher I am 18
$ echo I am lizhenya teacher I am 18 | awk 'BEGIN{RS=" "} length($1)<5{print $1}'
I
am
I
am
18
4、写个 shell,看看你的 linux 系统中是否有自定义用户(普通用户),若是有,一共有几个?
$ cat /etc/passwd | awk -F: '$3>=1000 && $NF != "/sbin/nologin"{total+=1}END{print "一共有"total"个普通用户"}'
一共有3个普通用户
5、写一个 shell 脚本来看看你使用最多的命令是哪些,列出你最常用的命令 top10
$ history | awk '{print $2}' | sort | uniq -c | sort -nr | head -10 | awk 'BEGIN{ idx=1 } {print idx,$2;idx+=1}'
6、编写一个脚本,计算 100 以内所有能被 3 整除数字的和
#!/bin/bash
total=0
for ((i=1;i<=100;i++));do
[ $[ i % 3 ] -eq 0 ] && let total=$total+$i
done
echo "1 ~ 100 内能被 3 整除数字的和为 $total"
练习三
填空
1、填写以下字符串测试操作符的意义
-n
:字符串不为空;-z
:字符串为空;
2、写出下面条件测试的含义
[ -e dir|file ]
:是否存在指定的目录为文件;[ -d dir ]
:是否存在指定的目录;[ -f file ]
:是否存在指定的文件;[ -r file ]
:当前用户对指定文件是否有读权限;[ -x file ]
:当前用户对指定文件是否有执行权限;[ -w file ]
:当前用户对指定文件是否有写权限;
简答
1、定义变量内容,不加引号、单引号、双引号、反引号结果有什么不同?应该怎么用?(3分)
- 不加引号:直接使用指定的内容,内容中有变量时变量会被替换,但是当内容中有空格时会报错;
- 单引号:按单引号中的内容原样输出;
- 双引号:会转义内容中的变量;
- 反引号:会将内容交给 bash 指定,将执行结果赋值给变量;
编程
1、将下面的条件表达式改写为 if 条件语句
[ -f /etc/hosts ] && echo !
#!/bin/bash
if [ -f /etc/hosts ];then
echo !
fi
2、写一个脚本,实现判断 10.0.1.0/24 网络里,当前在线用户的 IP 有哪些?
#!/bin/bash
for ip in 10.0.1.{1..253};do
ping -c 1 -W 1 -i 0.01 $ip &> /dev/null && echo $ip
done
3、用 shell 处理以下内容
the squid project provides a number of resources toassist users design,implement and support squid installations. Please browsethe documentation and support sections for more infomation
按单词出现频率降序排序
$ cat 1.txt | awk -F"[.,]" 'BEGIN{RS=" "} {print $1;if($2!="")print $2}' | sort | uniq -c | sort -nr | awk '{print $2}'
按字母出现频率降序排序!
$ cat 1.txt | sed -r 's/[^a-z]//g;s/([a-z])/\1 /g;' | xargs -n1 | sort | uniq -c | sort -nr | awk '{print $2}'
4、使用 ps aux
查看系统进程发现有 100 多个 test.sh
脚本正在运行,如何杀死所有的 test.sh
。
$ ps aux | grep 'test.sh' | grep 'grep' -v | awk '{print $2}' | xargs -i kill -9 {}
5、写一个猜数字脚本,当用户输入的数字和预设数字(随机生成一个 0-100 的数字)一样时,直接退出,否则让用户一直输入,并且提示用户的数字比预设数字大或者小
#!/bin/bash
random_num=$[RANDOM%100]
echo $random_num
read -p 'input a num: ' input_num
until [ $input_num -eq $random_num ]
do
[ $input_num -gt $random_num ] && echo '大了' || echo '小了'
read -p 'input a num: ' input_num
done
echo '恭喜你猜中了'
6、用 Shell 实现,把一个文本文档中只有一个数字的行给打印出来
$ cat 1.txt | awk '$0 ~ /^\s*[0-9]+\s*$/{print $0}' | egrep -o '[0-9]+'
7、写一个 Shell 脚本通过 curl 命令返回的状态码来判定所访问的网站是否正常,比如当前状态码 200,才算正常。
#!/bin/bash
curl -sI $1 | head -1 | grep '200 OK' &> /dev/null
if [ $? -eq 0 ];then
echo "正常"
else
echo "不正常"
fi
练习四
1、使用 while 循环使 1 加到 100
#!/bin/bash
i=1
while [ $i -lt 100 ];do
let i++
done
echo $i
2、查看磁盘/当前使用状态,如果使用率超过 80% 则把结果输出到/var/log/disk.err
#!/bin/bash
disk_used=`df -h | awk 'NR==2{print $(NF-1)}'`
disk_used=${disk_used/%\%*}
if [ $disk_used -gt 80 ];then
echo "${disk_used}%" > /var/log/disk.err
fi
3、脚本批量创建 10 个用户,密码统一为 123,需要对用户输入是否为数字和输入的名字是否为空做判断
#!/bin/bash
passwd='123'
count=1
until [ $count -gt 10 ];do
read -p "[${count}]输入要创建用户的用户名: " username
if [[ $username =~ ^[0-9]+$ ]] || [ -z $username ];then
echo "用户名不能为空或纯数字"
continue
fi
if `id $username &> /dev/null`;then
echo "该用户已存在"
continue
fi
useradd $username && echo $passwd | passwd $username --stdin &> /dev/null && echo "$username 用户已创建!"
let count++
done
4、使用 case 语句编写 nginx 启动脚本
#!/bin/bash
case "$1" in
'stop')
nginx -s stop &> /dev/null
;;
'start')
nginx &> /dev/null
;;
'reload')
nginx -s reload &> /dev/null
;;
*)
echo 'unknown option!!!'
;;
esac
if [ $? -eq 0 ];then
echo "$1 success !!"
else
echo "$1 failed !!!"
fi
5、要求:
• 执行脚本后,输入英文名字全拼,产生随机数 1-99 之间的数字,数字越大就去参加项目实践,前面已经抓到的数字,下次不能在出现相同数字。
• 第一个输入名字后,屏幕输出信息,并将名字和数字记录到文件里,程序不能退出继续等待别的学生输入。
#!/bin/bash
random_num(){
while :;do
random_num=$[RANDOM%100]
cat users.txt | awk '{print $2}' | egrep "^${random_num}$" &> /dev/null && continue
break
done
echo $random_num
}
while :;do
read -p '输入名字的拼音(退出请输入 exit): ' username
if [ $username == 'exit' ];then
echo '当前前三名: '
cat users.txt | awk '{print $2,$1}' | sort -nr | head -3
exit 0
fi
echo "$username $(random_num)" >> users.txt
done
6、打印一个菜单如下,然后用循环加case语句输出用户输入菜单选项的结果(8分)
h
显示命令帮助f
显示登陆信息d
显示磁盘挂载m
查看内存使用u
查看系统负载q
退出程序
#!/bin/bash
show_help(){
help_text="
\t\t|----------------|\n
\t\t| h 显示命令帮助 |\n
\t\t| f 显示登陆信息 |\n
\t\t| d 显示磁盘挂载 |\n
\t\t| m 查看内存使用 |\n
\t\t| u 查看系统负载 |\n
\t\t| q 退出程序\t |\n
\t\t|----------------|\n
"
echo -e $help_text
}
show_help
while :;do
read -p 'choose a option: ' option
case $option in
'h')
show_help
;;
'f')
last
;;
'd')
df -h
;;
'm')
free -m
;;
'u')
uptime
;;
'q')
exit 0
;;
esac
done
练习五
简答
1、写出 break
、continue
、exit
、return
的区别
break
:直接中断循环,继续向下执行continue
:终止当前循环,继续下一次循环exit
:直接终止当前程序的执行return
:用来返回一个函数的执行状态码,值为 0~255 之间
2、查看数组的索引与数组中元素的个数
- 数组索引:
${!test_arr[@]}
- 元素格式:
${#arr[*]}
3、数组 array=(1 2 3 4 5 6)
现在将数组中的 3
替换为 C
array[2]='C'
4、如何定义普通数组与关联数组
- 普通数组直接使用
(item1 item2 item3 ...)
的方式定义即可 - 关联数组需要使用
declare -A arr
显式声明
编程
1、生成 0-100 之间的随机数,并相加,直到大于 1000,输出相加的结果
#!/bin/bash
sum=0
until [ $sum -gt 1000 ];do
rand_num=$[RANDOM%100]
let sum+=$rand_num
done
echo $sum
2、生成 0-100 之间的随机数,并相加,直到大于1000,并判断最后一个随机数字能否被 3 整除
#!/bin/bash
sum=0
until [ $sum -gt 1000 ];do
rand_num=$[RANDOM%100]
let sum+=$rand_num
done
echo $sum
if [ $[rand_num % 3] -eq 0 ];then
echo "最后一个随机数是 $rand_num, 能被 3 整除"
else
echo "最后一个随机数是 $rand_num, 不能被 3 整除"
fi
3、判断 /tmp
目录下是否有大于 4k 的文件,如果有则输出该文件的大小与创建时间
$ ll /tmp/ | awk '$5>4096{print "大小: "$5/1024"K","创建时间: "$6,$7,$8}'
大小: 6.38379K 创建时间: Apr 11 12:00
4、数组 array=(1 2 3 4 5 6)
使用脚本打印出每个元素(每行显示一个元素)
#!/bin/bash
array=(1 2 3 4 5 6)
for i in ${array[*]};do
echo $i
done
5、使用数组判断 I am oldboy teacher welcome to training class
中字母数大于 6
的单词
#!/bin/bash
array=(I am oldboy teacher welcome to training class)
for word in ${array[*]};do
[ ${#word} -gt 6 ] && echo $word
done
练习六
1、检测服务器中重要的文件是否被修改吗如果被修改则报警(使用指纹)
#!/bin/bash
check_file="/etc/check_file"
# 将重要的文件或目录保存在数组中
important_path=(/etc/ /backup/)
[ $# -gt 1 ] && [ $1 == 'rebuild' ] && rm -f $check_file
if [ -e $check_file ];then
echo -e '校验失败的文件如下:\n'
md5sum -c $check_file 2> /dev/null | grep ': FAILED'
# 编写报警代码
else
echo '初始化校验文件'
for path in ${important_path[*]};do
if [ -f $path ];then
md5sum $path >> $check_file
elif [ -d $path ];then
find $path -type f | xargs -i md5sum {} >> $check_file
else
echo "$path: 路径错误, 只能是普通文件或目录"
fi
done
fi
2、计算 nginx 日志中访问最多的 10 个 IP 使用的流量总和
$ awk '{print $1}' access.log | sort | uniq -c | sort -nr -k1 | head -n 10 | awk '{total+=$1} END{print total}'
3、防止DOS攻击(检测 nignx 日志若某个 IP 短时间的 PV 过大则使用防火墙将其禁掉)
#!/bin/bash
# 下例使用 iptables 让每秒请求超过十个的 IP 禁止访问
for ip in `cat access.log | awk '{print $1" "$4}' | sort | uniq -c | awk '$1>2{print $2}'`;do
iptables -L | egrep ".*DROP.*$ip.*" &> /dev/null || iptables -t filter -A INPUT -s $ip -p tcp -j DROP
done
4、实时监控服务器 CPU 使用率大于 80%、磁盘使用率大于 80%,内存使用率大于 80% 时报警
#!/bin/bash
cpu_used=`vmstat | awk 'NR==3{print (100-$(NF-2))}'`
disk_used=`df -h | awk 'NR==2{sub("%","");print $(NF-1)}'`
mem_used=`free -m | awk 'NR==2{print $3/$2*100}'`
mem_used=${mem_used%.*}
if [ $cpu_used -gt 80 ];then
echo 'CPU 过载'
fi
if [ $disk_used -gt 80 ];then
echo '磁盘过载'
fi
if [ $mem_used -gt 80 ];then
echo '内存过载'
fi
5、使用源码编译安装 nignx(脚本可以重复执行)。
#!/bin/bash
#
nginx_version='1.16.1'
file_name="nginx-${nginx_version}"
# 安装编译安装需要的依赖包
yum -y install gcc gcc-c++ make automake autoconf libtool pcre* zlib openssl openssl-devel libxml2 libxml2-dev libxslt-devel gd-devel perl-devel perl-ExtUtils-Embed gperftools gperftools-*
# 添加 nginx 用户
id nginx &> /dev/null || useradd -s /sbin/nologin -M nginx
# 检查是否已安装了 nginx
if [ -f /usr/sbin/nginx ];then
echo "已安装了如下版本的 nginx:"
/usr/sbin/nginx -v
exit 1
fi
# 下载 Nginx
[ -f /tmp/${file_name}.tar.gz ] || wget https://mirrors.huaweicloud.com/nginx/${file_name}.tar.gz -O /tmp/${file_name}.tar.gz
[ $? -eq 0 ] && echo '下载源码包成功' || echo '下载源码包失败'
# 解压
cd /tmp && tar xf ${file_name}.tar.gz
[ $? -eq 0 ] && echo '解压成功' || echo '解压失败'
# 编译
cd /tmp/nginx-${nginx_version} && ./configure --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --pid-path=/run/nginx.pid --lock-path=/run/lock/subsys/nginx --user=nginx --group=nginx --with-file-aio --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-stream_ssl_preread_module --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module --with-http_stub_status_module --with-http_perl_module=dynamic --with-http_auth_request_module --with-mail=dynamic --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream=dynamic --with-stream_ssl_module --with-google_perftools_module --with-debug --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mtune=generic' --with-ld-opt='-Wl,-z,relro -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -Wl,-E'
# 安装
make && make install
[ $? -eq 0 ] && echo '安装成功' || echo '安装失败'
# 初始化目录
mkdir /var/lib/nginx/tmp/ -p
6、数据库分库分表备份到 /tmp
下
评论区