shell 练习
1. 备份并压缩 /etc 下所有内容到 /root/bak,存放形式为 2020_2_15_etc.tar.bz2。
#!/bin/bash DestDir=/root/bak DateName=$(date +%Y_%m_%d) [ "$UID" -ne 0 ] && echo "You need to be root to perform this command." && exit cd /etc tar cjf ${DestDir}/${DateName}.tar.bz2 *
查看是否为root用户,用 $UID
shell 进行的cd目录不需要切换回来,因为是子进程进行的
2. 查看内存占用率,如果大于80%则报警
#!/bin/bash Use=$(free | awk '/^Mem/{print $3/$2*100}') [ ${Use%.*} -gt 80 ] && echo "warning" || echo "ok"
注意只能比较整数,首先用 ${VAR%MOD}的到整数
注意整数比大小用 -gt,字符串用 >=
3.
#!/bin/bash string="Bash is an excellent excellent programming language language" echo "${string}" cat << eof 1] get the length of string 2] delete all language 3] replace first excellent with best 4] replace all excellent with best eof read -p "please input [1|2|3|4] : " var case $var in 1) echo $(echo ${string} | wc -c) ;; 2) echo ${string//language/} ;; 3) echo ${string/excellent/best} ;; 4) echo ${string//excellent/best} ;; *) ;; esac
4. 查看sshd服务状态,进程是否启动,端口状态
#!/bin/bash # 1. 判断服务状态 ssh_status=$(systemctl status sshd | awk '/^ +Active/{print $2}') if [ "$ssh_status" == "active" ]; then echo "服务状态已启动..." else echo "服务状态未启动..." fi # 2. 判断服务端口号 netstat -ntlp |grep sshd | grep -v grep &>/dev/null if [ $? -eq 0 ]; then echo "服务端口正常" else echo "服务端口异常" fi # 3. 判断服务进程是否存在 ps -aux |grep sshd | grep -v grep &>/dev/null if [ $? -eq 0 ]; then echo "服务进程正常" else echo "服务进程异常" fi
5. 查看系统版本
tt=$(cat /etc/red | awk '{print $(NF-1)}')
6. 实现rsync的服务脚本
#!/bin/bash RsyncLock=/var/run/rsync.pid source /etc/init.d/functions case $1 in start) if [ -f ${RsyncLock} ]; then action "Rsync is Running ..." /bin/false else touch ${RsyncLock} rsync --daemon action "Rsync Started ..." /bin/true fi ;; stop) if [ -f ${RsyncLock} ]; then rm ${RsyncLock} killall rsync action "Rsync Killed ..." /bin/true else action "Rsync is not Running ..." /bin/false fi ;; status) if [ -f ${RsyncLock} ]; then RsyncPid=$(ps aux |grep rsync | grep -v grep | awk '/ rsync /{print $2}') echo "Rsync is Running ( $RsyncPid )" else echo "Rsync is not Running" fi ;; *) echo "Usage : $0 [start | stop | status ]" ;; esac
7.实现nginx服务脚本
相对于上一脚本,添加了 nginx -t 的检查,和整个脚本的锁机制。
#!/bin/bash Nginx=/usr/local/nginx/sbin/nginx Lock=/tmp/${0}.lock echo_result() { if [ "$1" -eq 0 ]; then action "$2" /bin/true else action "$2" /bin/false rm -f ${Lock} exit fi } nginx_test() { ${Nginx} -t &>/dev/null if [ "$?" -ne 0 ]; then read -p "nginx.conf have error, do you need to modify [y|n]? " rc case "$rc" in y|Y|Yes|yes|YES) ${Nginx} -t &>/tmp/${0}.err ErrLine=$(cat /tmp/xxx.err | awk -F: '/:[0-9]+$/{print $NF}') rm /tmp/${0}.err vi /usr/local/nginx/conf/nginx.conf +${ErrLine} ;; n|N|No|NO) ;; *) echo "input [y|n]" ;; esac fi } source /etc/init.d/functions if [ -f ${Lock} ]; then echo "command is running, please wait..." exit else touch ${Lock} fi [ "$UID" -ne 0 ] && echo "you need to be root to run this command !" && exit case "$1" in start) if [ -e /var/run/nginx.pid ]; then action "nginx is starting" /bin/false else nginx_test ${Nginx} &>/dev/null echo_result $? "nginx start" touch /var/run/nginx.pid fi ;; stop) if [ -e /var/run/nginx.pid ]; then nginx_test ${Nginx} -s stop &>/dev/null echo_result $? "nginx stop" rm -f /var/run/nginx.pid else action "nginx is not starting" /bin/false fi ;; reload) if [ -e /var/run/nginx.pid ]; then nginx_test ${Nginx} -s reload &>/dev/null echo_result $? "nginx reload" else action "nginx is not starting" /bin/false fi ;; status) nginx_pid=$(ps aux | grep "nginx: master" | grep -v grep | awk '{print $2}') if [ -z ${nginx_pid} ]; then action "nginx is not starting" /bin/false else action "nginx is running ( ${nginx_pid} )" /bin/true fi ;; *) echo "Usage : $0 [start | stop | reload | status]" ;; esac rm -f ${Lock}
8. 批量创建用户
#!/bin/bash [ $UID -ne 0 ] && echo "you must to be root to run this command !" && exit read -p "please input name prefix :" Prefix [ -z "${Prefix}" ] && echo "please input vaild value" && exit read -p "please input num :" Num if [[ ! ${Num} =~ ^[0-9]+$ ]]; then echo "please input integer" exit fi read -p "confirm create ${Prefix}1 ~ ${Prefix}${Num} [y|n]" rc case "$rc" in y|Y|yes|YES|Yes) for n in $(seq ${Num}) do Name=${Prefix}${n} id ${Name} &>/dev/null if [ $? -eq 1 ]; then user_passwd=$(echo ${RANDOM} | md5sum | cut -c 1-6) adduser ${Name} echo ${user_passwd} | passwd ${Name} --stdin &>/dev/null echo "${Name} ${user_passwd}" >> /tmp/user.log echo "Success to add ${Name}" else echo "${Name} already exists" fi done ;; n|N|no|No|NO) exit ;; *) exit ;; esac
9. 批量删除用户
#!/bin/bash [ $UID -ne 0 ] && echo "you must to be root to run this command !" && exit read -p "please input name prefix :" Prefix [ -z "${Prefix}" ] && echo "please input vaild value" && exit read -p "please input num :" Num if [[ ! ${Num} =~ ^[0-9]+$ ]]; then echo "please input integer" exit fi read -p "confirm delete ${Prefix}1 ~ ${Prefix}${Num} [y|n] : " rc case "$rc" in y|Y|yes|YES|Yes) for n in $(seq ${Num}) do Name=${Prefix}${n} id ${Name} &>/dev/null if [ $? -eq 0 ]; then userdel -r ${Name} [ $? -eq 0 ] && echo "${Name} success to del" || echo "${Name} failed to del" else echo "${Name} not exists" fi done ;; n|N|no|No|NO) exit ;; *) exit ;; esac
10. IP探测
#!/bin/bash Network="192.168.1" for n in {1..254} do { Address="${Network}.${n}" ping -c 1 -W 1 ${Address} &>/dev/null [ $? -eq 0 ] && echo "${Address} is alive" || echo "${Address} is down" } & done wait echo "ip detection complete"
使用 { ... } & 的作用是,让括号内的代码成后台进程,不影响主shell进程的执行,进而实现并发执行。
wait 的作用是,等待所有进程执行完成
11. 猜数字
#!/bin/bash random_num=$((${RANDOM}%100+1)) echo "$random_num" while true do read -p "Please input your answer, [q] to exit : " rc [ "${rc}" == "q" ] && exit if [[ ! ${rc} =~ ^[0-9]+$ ]]; then echo "Please input integer" continue fi [ "${rc}" -eq ${random_num} ] && echo "Congratulations on success !" && break if [ "${rc}" -gt ${random_num} ]; then echo "Guess big" else echo "Guess small" fi let i++ [ $i -gt 5 ] && echo "Run out of 6 chances !" && break done
12. 从文本读取用户名密码,并用while创建用户,设置密码
#!/bin/bash while read line do user_name=${line%:*} user_passwd=${line#*:} id ${user_name} &>/dev/null if [ $? -eq 0 ]; then echo "${user_name} is exists" else useradd ${user_name} echo ${user_passwd} | passwd ${user_name} --stdin &>/dev/null [ $? -eq 0 ] && echo "${user_name} create succeed" || echo "${user_name} create failed" fi done <user.txt
13. 使用关联数组,统计元素个数
#!/bin/bash declare -A array_pass while read line do key=$(echo $line | awk -F: '{print $NF}') let array_pass[$key]++ done</etc/passwd for n in ${!array_pass[@]} do echo "$n : ${array_pass[$n]}" done
关联数组需要先声明
awk '{ips[$2]++} END{for(i in ips) print i,ips[i]}' user.txt
要统计谁,谁就作为索引。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?