Shell 脚本解锁 curl/iptables/Nginx 日志分析等实战用法

1、写一个shell脚本,通过curl -I 返回的状态码来判定所访问的网站是否正常。

比如,当状态码为200时,才算正常。

bash 复制代码
#!/bin/bash
#这个脚本用来判断一个网址是否正常
#作者:猿课-阿铭 www.apelearn.com
#日期:2018-11-01

url="http://www.apelearn.com/index.php"
mail_user=306798658@qq.com

code=`curl -I $url 2>/tmp/curl.err|head -1|awk '{print $2}'`
if [ -z "$code" ]
then
    python mail.py $mail_user "$url访问异常" "`cat /tmp/curl.err`"
    exit
elif [ $code != "200" ]
then
    curl -I $url &> /tmp/curl.log
    python mail.py $mail_user "$url访问异常 状态码$code" "`/tmp/curl.log`" 
fi
2、将用户家目录(考虑到执行脚本的用户可能是普通用户也可能是root)下面小于5KB的文件打包成tar.gz的压缩包,并以当前日期为文件名前缀,例如,2018-03-15.tar.gz。
bash 复制代码
#!/bin/bash

t=`date +%F`
cd $HOME
tar czf $t.tar.gz `find ./ -type f -size -5k|xargs`
3、一个同学不小心用iptables规则把sshd端口22给封掉了,结果不能远程登陆,要想解决这问题,还要去机房,登录真机去删除这规则。 问题来了,要写个监控脚本,监控iptables规则是否封掉了22端口,如果封掉了,给打开。 写好脚本,放到任务计划里,每分钟执行一次。
bash 复制代码
#!/bin/bash

iptables -nvL INPUT --line-numbers |grep -w 'dpt:22' |awk '$4 ~/REJECT|DROP/ {print $1}' > /tmp/iptables.log
n=`wc -l /tmp/iptables.log`

if [ $n -gt 0 ]
then
    for n in `tac /tmp/iptables.log`
    do
	iptables -D INPUT $n
    done
fi

4、已知nginx访问的日志文件在/usr/local/nginx/logs/access.log内,请统计下早上10点到12点 来访ip最多的是哪个?

参考日志

```

111.199.186.68 -- [15/Sep/2017:09:58:37 +0800] "//plugin.php?id=security:job" 200 "POST //plugin.php?id=security:job HTTP/1.1″"http://a.lishiming.net/forum.php?mod=viewthread\&tid=11338\&extra=page%3D1%26filter%3Dauthor%26orderby%3Ddateline" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3141.7 Safari/537.36"

203.208.60.208 -- [15/Sep/2017:09:58:46 +0800] "/misc.php?mod=patch&action=ipnotice&_r=0.05560809863330207&inajax=1&ajaxtarget=ip_notice" 200 "GET /misc.php?mod=patch&action=ipnotice&_r=0.05560809863330207&inajax=1&ajaxtarget=ip_notice HTTP/1.1″"http://a.lishiming.net/forum.php?mod=forumdisplay\&fid=65\&filter=author\&orderby=dateline" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3141.7 Safari/537.36"

```

bash 复制代码
#!/bin/bash
#这个脚本用来分析Nginx访问日志
#作者:猿课-阿铭 www.apelearn.com
#日期:2018-11-01

export LANG=en
log="/usr/local/nginx/logs/access.log"
t=`date +%d/%b/%Y:1[01]:[0-5][0-9]:`

egrep "$t" $log|awk '{print $1}' |sort -n |uniq -c |sort -n |tail -1 |awk '{print $2}'
5、写一个shell脚本。提示输入一个暂停的数字,然后从1打印到该数字。然后询问是否继续。继续的话再输入一个数字接着打印,否则退出脚本。

例:如果输入的是5,打印1 2 3 4 5,然后继续输入15,然后打印6 7 ...14 15 以此类推。

bash 复制代码
#!/bin/bash
#这个脚本用来打印数字
#作者:猿课-阿铭 www.apelearn.com
#日期:2018-11-01

read -p "Please input a number: " n
n1=`echo $n |sed 's/[0-9]//g'`
if [ -n "$n1" ]
then
    echo "Please input a number."
    exit
fi

for i in `seq 1 $n`
do
    echo $i
done

read -p "If continue? y/n" c

case $c in
  n|N)
    exit
    ;;
  y|Y)
    read -p "Please input a number: " n2
    n3=`echo $n2|sed 's/[0-9]//g'`
    if [ -n "$n3" ]
    then
	echo "Please input a number."
	exit
    fi
    if [ $n2 -le $n ]
    then
	echo "$n2 should grater than $n."
        exit
    fi
    for i in `seq $[$n+1] $n2`
    do
	echo $i
    done
    ;;
  *)
    echo "Please input y or n."
    ;;
esac
6、在文本文档1.txt第5行(假设文件行数大于5)后面增加如下内容:

This is a test file.

Test insert line into this file.

bash 复制代码
#!/bin/bash

n=0
cat 1.txt |while read line
do
    n=$[$n+1]
    if [ $n -eq 5 ]
    then
        echo $line
	echo -e "# This is a test file.\n# Test insert line into this file."
    else
	echo $line
    fi
done
7、设计一个shell程序,在每月第一天备份并压缩/etc目录的所有内容,存放在/root/bak目录里,且文件名为如下形式"yymmdd_etc.tar.gz",yy为年,mm为月,dd为日。
bash 复制代码
#!/bin/bash
d1=`date +%d`
d2=`date +%y%m%d`

if [ $d1 == "01" ]
then
    cd /etc/
    tar czf /root/bak/$d2_etc.tar.gz ./
fi
8、将文件内所有的单词的重复次数计算出来,只需要列出重复次数最多的10个单词。
bash 复制代码
#!/bin/bash

for w in `sed 's/[^a-zA-Z]/ /g' $1`
do
    echo $w
done |sort |uniq -c |sort -nr|head
9、需求是,把所有的成员平均分成若干个小组。这里,提供一个人员列表,比如成员有50人,需要分成7个小组,要求随机性,每次和每次分组的结果应该不一致。

xiaoguisheng

guoyuqing

xiongyongzheng

mengjintang

chaizuzhou

zhousheng

xufangming

zhaoliangyun

hanshiru

wangxianyi

zhangjipei

luxiuli

yangshugen

guoyongzhi

lijianguo

wuqiongchen

dinglin

yaoyashan

yinzijia

wangbencheng

liuxiuwen

chenzuqi

leyuguo

baozongyao

fenghao

sunxiaoquan

zhangyaxian

lijiuzhe

dulichun

lixi

shenpeiwen

zousilin

luoping

chaiyan

fandaozhang

huzixiang

jinzhen

zhujunfeng

liqianbiao

hangyanliang

luorenjian

loujianji

fujianzhou

gengyiwu

jinjigui

liuzhizhong

lisanyan

lisili

zhangyiyu

songguozhen

zhangxinghua

zhaozhiyong

huanghe

xiaojie

fanhongfei

wangguiwen

renshumin

songfuying

zhanghaibo

liguangqun

puaihua

yanzhihua

gaojixian

liulai

funing

chenruizhi

chendaxin

laishaoying

xujian

xiaozhekou

xuxiaping

jiangchunqing

bash 复制代码
#!/bin/bash

#人员列表文件
f=member.txt
#小组数
group_n=7
#人员总数
member_n=`wc -l $f|awk '{print $1}'`

#根据姓名计算该用户所在小组的id
get_n()
{
    #根据姓名计算cksum值
    l=`echo $1|cksum|awk '{print $1}'`
    #获取一个随机数
    n1=$RANDOM
    #cksum值和随机数相加,然后除以小组数取余,这样可以确保每次获取到的余数都不一样
    n2=$[$n1+$l]
    g_id=$[$n2%$group_n]
    #假如小组数为7,则余数范围0-6,如果余数为0,则小组为7
    if [ $g_id -eq 0 ]
    then
        g_id=$group_n
    fi
    echo $g_id
}

for i in `seq 1 $group_n`
do
    #n_$i.txt为临时文件,用来记录该小组内的成员
    #脚本之前执行过,则该文件会存在,本次执行脚本前应该删除掉这个临时文件
    [ -f n_$i.txt ] && rm -f n_$i.txt
done


shuf $f|while read name
do
    #计算用户所在小组的id
    g=`get_n $name`
    #将人员追加写入到他对应的小组里
    echo $name >> n_$g.txt
done

#定义计算文件行数的函数
nu(){
    wc -l $1|awk '{print $1}'
}

#获取组员人数最多的小组
max(){
    ma=0
    for i in `seq 1 $group_n|shuf`
    do
        n=`nu n_$i.txt`
        if [ $n -gt $ma ]
        then
            ma=$n
       fi
    done
    echo $ma
}

#获取组员人数最少的小组
min(){
    mi=$member_n
    for i in `seq 1 $group_n|shuf`
    do
       n=`nu n_$i.txt`
       if [ $n -lt $mi ]
       then
           mi=$n
       fi
    done
    echo $mi
}

#定义四舍五入函数
div()
{
    n=`echo "scale=1;$1/$2"|bc`
    n1=`echo "scale=1;$n+0.5"|bc`
    echo $n1|cut -d. -f1
}

#小组组员平均值(非四舍五入)
ava_n=$[$member_n/$group_n]
#小组组员平均值(四舍五入)
ava_n1=`div $member_n $group_n`

if [ $ava_n -eq $ava_n1 ]
then
    #定义初始最小值
    ini_min=1
    #以下while循环要做的事情,就是要把人数多的组里的人搞到人数少的组里去
    #此while循环的条件是,当人数最少的组成员数小于组员平均值
    while [ $ini_min -lt $ava_n1 ]
    do
        #找出人数最多的组
        m1=`max`
        #找出人数最少的组
        m2=`min`
        for i in `seq 1 $group_n|shuf`
        do
            n=`nu n_$i.txt`
            #找到人数最多的组对应的文件f1(可能有多个,这里取出现的第一个即可)
            if [ $n -eq $m1 ]
            then
                f1=n_$i.txt
            #找到人数最少的组对应的文件f2(可能有多个,这里取出现的第一个即可)
            elif [ $n -eq $m2 ]
            then
                f2=n_$i.txt
            fi
        done
        #取f1中最后一个人名
        name=`tail -n1 $f1`
        #将这个人名追加写入f2中
        echo $name >> $f2
        #在f1中删除刚刚取走的人名
        sed -i "/$name/d" $f1
        #把此时的最少组人员数赋值给ini_min
        ini_min=`min`
    done
else
    #定义初始最大值
    ini_max=$member_n
    while [ $ini_max -gt $ava_n1 ]
    do
        #找出人数最多的组
        m1=`max`
        #找出人数最少的组
        m2=`min`
        for i in `seq 1 $group_n|shuf`
        do
            n=`nu n_$i.txt`
            #找到人数最多的组对应的文件f1(可能有多个,这里取出现的第一个即可)
            if [ $n -eq $m1 ]
            then
                f1=n_$i.txt
                #找到人数最少的组对应的文件f2(可能有多个,这里取出现的第一个即可)
            elif [ $n -eq $m2 ]
            then
                f2=n_$i.txt
            fi
        done
        #取f1中最后一个人名
        name=`tail -n1 $f1`
        #将这个人名追加写入f2中
        echo $name >> $f2
        #在f1中删除刚刚取走的人名
        sed -i "/$name/d" $f1
        #把此时的最少组人员数赋值给ini_min
        ini_max=`max`
    done
fi

for i in `seq 1 $group_n`
do
    echo -e "\033[34m$i 组成员有:\033[0m"
    cat n_$i.txt
    #把临时文件删除
    rm -f n_$i.txt
    echo
done
10、写一个shell脚本,比较两个数的大小,支持浮点数,两个数通过shell参数的形式提供。
bash 复制代码
#!/bin/bash

if [ $# -ne 2 ]
then
    echo "请提供两个参数."
    exit
fi

if_number() 
{
    if echo $1|grep -q '^-'
    then
	nu=`echo $1|sed 's/^-//'`
    else
	nu=$1
    fi
    n=`echo $nu|sed 's/[0-9.]//g'`
    if [ -n "$n" ]
    then
	echo "$1不是合法数字."
	exit
    fi
    if echo $1|grep -q '^\.'
    then
	echo "$1不是合法数字."
	exit
    fi
}

if_number $1
if_number $2

n1=`echo "$1>$2"|bc`
if [ $n1 -eq 1 ]
then
    echo "$1 > $2"
else
    if [ "$1" == "$2" ]
    then
	echo "$1 = $2"
    else
	echo "$1 < $2"
    fi
fi
11、有两个文件a.txt和b.txt,需求是,把a.txt中有的但b.txt中没有的行找出来,并写入到c.txt,然后计算c.txt文件的行数。
bash 复制代码
#!/bin/bash

cat a.txt|while read line
do
    if ! grep -q "$line" b.txt
    then
	echo $line
    fi
done >c.txt
wc -l c.txt
12、把当前用户下所有进程名字中含有"aming"的进程关闭。
bash 复制代码
#!/bin/bash

ps -u $USER|awk '$NF ~ /aming/ {print $1}' |xargs kill
13、用shell实现,以并发进程的形式将mysql数据库所有的表备份到当前目录,并把所有的表压缩到一个压缩包文件里。

假设数据库名字为mydb,用户名为aming,密码为passwd。

bash 复制代码
#!/bin/bash

N=5
mysql -uaming -ppasswd mydb -e "show tables"|sed '1d' > /tmp/table.txt
n=`wc -l /tmp/table.txt|awk '{print $1}'

div()
{
    n=`echo "scale=1;$1/$2"|bc`
    n1=`echo "scale=1;$n+0.5"|bc`
    echo $n1|cut -d. -f1
}

n1=`div $n $N`

split -l $n1 /tmp/table.txt 

myd()
{
    for t in `cat $1`
    do
    	mysqldump -uaming -ppasswd mydb $t > $t.sql
    done
}

for f in xaa xab xac xad xae
do
    myd $f &
done

wait 
tar czf mydb.tar.gz *.sql
rm -f *.sql 
14、一个网站,使用了cdn,全国各地有几十个节点。需要你写一个shell脚本来监控各个节点是否正常。

假如

  1. 监控的url为www.aming.com/index.php
  2. 源站ip为88.88.88.88。
bash 复制代码
#!/bin/bash

s_ip=88.88.88.88
url=www.aminglinux.com/index.php
ipf=/data/ip.list

curl -x$s_ip:80 $url 2>/dev/null >/tmp/source.txt
for ip in `cat $ipf`
do
    curl -x$ip:80 $url 2>/dev/null >/tmp/$ip.txt
    diff /tmp/source.txt /tmp/$ip.txt > /tmp/$ip.diff

    n=`wc -l /tmp/$ip.diff|awk '{print $1}'`
    if [ $n -gt 0 ]
    then
	echo "节点$ip有异常."
    fi
done
15、已知下面的字符串是通过RANDOM随机数变量md5sum|cut -c 1-8截取后的结果,请破解这些字符串对应的md5sum前的RANDOM对应数字?

21029299
00205d1c
a3da1677
1f6d12dd
890684ba

bash 复制代码
#!/bin/bash

for i in `seq 0 32767`
do
    m=`echo $i|md5sum |cut -c 1-8 `
    echo $i $m 
done > /tmp/md5.txt

cat > c.txt <<EOF
21029299
00205d1c
a3da1677
1f6d12dd
890684ba
EOF

grep -f c.txt /tmp/md5.txt
16、写一个脚本:
  1. 判断当前主机的CPU生产商,其信息在/proc/cpuinfo文件中vendor id一行中。
  2. 如果其生产商为AuthenticAMD,就显示其为AMD公司;
  3. 如果其生产商为GenuineIntel,就显示其为Intel公司;
  4. 否则,就说其为非主流公司。
bash 复制代码
#!/bin/bash

cpu=`grep '^vendor_id' /proc/cpuinfo |head -1|awk -F ': ' '{print $2}'`
#if [ $cpu == "AuthenticAMD" ]
#then
#   echo "CPU厂商是AMD."
#elif [ $cpu == "GenuineIntel" ]
#then
#   echo "CPU厂商是Intel."
#else
#   echo "CPU厂商是非主流厂商。"
#fi

case $cpu in
  AuthenticAMD)
	echo "CPU厂商是AMD."
  ;;

  GenuineIntel)
	echo "CPU厂商是Intel."
  ;;
  
  *)
	echo "CPU厂商是非主流厂商。"
  ;;
esac
17、用shell写一个监控服务器cpu使用率的监控脚本。
bash 复制代码
#!/bin/bash

mail_user=xxx@xxx.com

m_mail() {
    log=$1
    t_s=`date +%s`
    t_s2=`date -d "1 hours ago" +%s`
    if [ ! -f /tmp/$log ]
    then
        #创建$log文件
        touch /tmp/$log 
        #增加a权限,只允许追加内容,不允许更改或删除
        chattr +a /tmp/$log
        #第一次告警,可以直接写入1小时以前的时间戳
        echo $t_s2 >> /tmp/$log
    fi
    #无论$log文件是否是刚刚创建,都需要查看最后一行的时间戳
    t_s2=`tail -1 /tmp/$log|awk '{print $1}'`
    #取出最后一行即上次告警的时间戳后,立即写入当前的时间戳
    echo $t_s>>/tmp/$log
    #取两次时间戳差值
    v=$[$t_s-$t_s2]
    #如果差值超过1800,立即发邮件
    if [ $v -gt 1800 ]
    then
        #发邮件,其中$2为mail函数的第二个参数,这里为一个文件
        python mail.py $mail_user "CPU使用率超过90%" "`top -bn1`"  2>/dev/null   
        #定义计数器临时文件,并写入0         
        echo "0" > /tmp/$log.count
    else
        #如果计数器临时文件不存在,需要创建并写入0
        if [ ! -f /tmp/$log.count ]
        then
            echo "0" > /tmp/$log.count
        fi
        nu=`cat /tmp/$log.count`
        #30分钟内每发生1次告警,计数器加1
        nu2=$[$nu+1]
        echo $nu2>/tmp/$log.count
        #当告警次数超过30次,需要再次发邮件
        if [ $nu2 -gt 30 ]
        then
             python mail.py $mail_user "CPU使用率超过90%持续30分钟了" "`top -bn1`" 2>/dev/null  
             #第二次告警后,将计数器再次从0开始          
             echo "0" > /tmp/$log.count
        fi
    fi
}

while :
do
    cpu_i=`top -bn1 |grep 'Cpu(s):'|sed 's/^%//'|awk -F ' +|%' '{print $8}'`
    cpu_u=`echo 100-$cpu_i|bc`

    if [ $cpu_u -gt 90 ]
    then
       m_mail cpu
    fi
    sleep 60
done
18、给出一个进程PID,打印出该进程下面的子进程以及子进程下面的所有子进程。(只需要考虑子进程的子进程,再往深层次则不考虑)
bash 复制代码
#!/bin/bash

ps -elf > /tmp/pid.txt
read -p "Please input a pid: " p

if [ -z "$p" ]
then
    echo "你没有输入任何pid,请输入一个pid."
    exit
fi

if ! grep -qw "$p" /tmp/pid.txt
then
    echo "你输入的pid不存在."
    exit
fi

get_cpid()
{
    p1=$1
    ps -elf |awk -v p2=$p1 '$5==p2 {print $4}' > /tmp/$p1.txt
    n=`wc -l /tmp/$p1.txt|awk '{print $1}'`
    if [ $n -eq 0 ]
    then
	echo "进程$1下没有子进程."
    else
	echo "进程$1下的子进程是:"
	cat /tmp/$p1.txt
    fi
}

get_cpid $p

for c_p in `cat /tmp/$p.txt`
do 
    get_cpid $c_p
done
19、需求背景:

服务器上,跑的lamp环境,上面有很多客户的项目,每个项目就是一个网站。 由于客户在不断增加,每次增加一个客户,就需要配置相应的mysql、ftp以及httpd。这种工作重复性非常强的,所以用脚本实现非常合适。mysql增加的是对应客户项目的数据库、用户、密码,ftp增加的是对应项目的用户、密码(使用vsftpd,虚拟用户模式),httpd就是要增加虚拟主机配置段。

bash 复制代码
#!/bin/bash

#网站目录
webdir=/data/wwwroot

#ftp的虚拟用户配置文件目录
ftpudir=/etc/vsftpd/vuuser

#ftp虚拟用户密码文件
ftpuserfile=/root/login

#mysql命令行登录root
mysqlc="/usr/local/mysql/bin/mysql -uroot -pjk1hYUcnt6"

#apache虚拟主机配置文件
httpd_config_f="/usr/local/apache2/conf/extra/httpd-vhosts.conf"

#定义增加MySQL库和用户的函数
add_mysql_user()
{
    #生成随机密码
    mysql_p=`mkpasswd -s 0 -l 12`

    #将密码保存到临时文件里,这里的$pro为用户自定义的项目名字
    echo "$pro $mysql_p" >/tmp/$pro.txt

    #这里使用嵌入文档的形式(需顶格),将创建用户并授权的命令传递给mysql    
$mysqlc <<EOF
create database $pro;
grant all on $pro.* to "$pro"@'127.0.0.1' identified by "$mysql_p";
#下面这个EOF必须要顶格
EOF
}

#定义增加FTP用户的函数
add_ftp_user()
{
    ftp_p=`mkpasswd -s 0 -l 12`
    echo "$pro" >> $ftpuserfile
    echo "$ftp_p" >> $ftpuserfile

    #将用户、密码文件转换为密码db文件
    db_load -T -t hash -f $ftpuserfile  /etc/vsftpd/vsftpd_login.db
    cd $ftpudir

    #这里的aaa是一个文件,是之前的一个项目,可以作为配置模板
    cp aaa $pro 

    #把里面的aaa改为新的项目名字
    sed -i "s/aaa/$pro/" $pro 

    #重启vsftpd服务
    /etc/init.d/vsftpd restart
}

#定义增加apache虚拟主机的函数
config_httpd()
{
    #增加网站根目录,和域名保持一致,这里的$dom为用户自定义的域名
    mkdir $webdir/$dom

    #将网站根目录属主和属组设置为ftp用户
    chown vsftpd:vsftpd $webdir/$dom
    
    #用嵌入文档(需顶格),把虚拟主机配置写入到配置文件里
cat >> $httpd_config_f <<EOF
<VirtualHost *:80>
    DocumentRoot $webdir/$dom
    ServerName $dom
    <Directory $webdir/$dom>
        AllowOverride none
        Require all granted  
    </Directory>
</VirtualHost>
EOF
   
    #重载apache服务
    /usr/local/apache2/bin/apachectl graceful
}

read -p "input the project name: " pro
read -p "input the domain: " dom

add_mysql_user
add_ftp_user
config_httpd
20、用shell写一个简易计算器,可以实现加、减、乘、除运算,假如脚本名字为1.sh,执行示例:./1.sh 1 + 2
bash 复制代码
#!/bin/bash

if [ $# -ne 3 ]
then
    echo "你给的参数个数不对,应该给3个参数."
    exit
fi

if_number()
{
    n1=`echo $1|sed 's/[0-9.]//g'`
    if [ -n "$n1" ]
    then
	echo "$1不是数字."
	exit
    fi

    if echo $1|grep -q '^\.' 
    then
	echo "数字$1不合法."
        exit
    fi
}

if_number $1
if_number $3

case $2 in 
  +)
    echo "$1+$3"|bc
    ;;
  -)
    echo "$1-$3"|bc
    ;;
  \*)
    echo "$1*$3"|bc
    ;;
  /)
    echo "scale=2;$1/$3"|bc
    ;;
  *)
    echo "你给出的格式不对,第二个参数只能是+,-,*,/"
    ;;
esac
21、1. 判断所给目录内哪些二级目录下有没有text.txt文件。
  1. 有text.txt文件的二级目录,计算出该test.txt文件里面所给出单词的次数。
  2. 假如脚本名字为1.sh, 运行脚本的格式为 ./1.sh 123 root,其中123为目录名字,而root为要计算数量的单词。
bash 复制代码
#!/bin/bash

if [ $# -ne 2 ]
then
    echo "请提供两个参数,第一个参数是目录名字,第二个参数是单词"
    exit
fi

cd $1
for f in `ls .`
do
    if [ -d $f ]
    then
	if [ -f $f/test.txt ]
	then
	    n=`grep -cw "$2" $f/test.txt`
	    echo  "$1/$f目录下面有test.txt, 该test.txt里面的有$n个$2."
	fi
    fi
done
22、交互式脚本,根据提示,需要用户输入一个数字作为参数,最终打印出一个正方形。在这里我提供一个linux下面的特殊字符■,可以直接打印出来。

示例: 如果用户输入数字为5,则最终显示的效果为

```

■ ■ ■ ■ ■

■ ■ ■ ■ ■

■ ■ ■ ■ ■

■ ■ ■ ■ ■

■ ■ ■ ■ ■

```

bash 复制代码
#!/bin/bash


while :
do
    read -p "Please input a nuber: " n
    n1=`echo $n|sed 's/[0-9]//g'`
    if [ -n "$n1" ]
    then
        echo "$n is not a nuber."
        continue
    else
	break
    fi
done

for i in `seq 1 $n`
do
    for j in `seq 1 $n`
    do
	echo -n "■ "
    done
    echo 
done
23、写一个脚本,依次向/etc/passwd中的每个用户问好,并且说出对方的ID是什么,如:

Hello, root,your UID is 0.

bash 复制代码
#!/bin/bash

cat /etc/passwd |while read line
do
    username=`echo $line|awk -F ':' '{print $1}'`
    uid=`echo $line|awk -F ':' '{print $3}'`
    echo "Hello, $username, your uid is $uid."
done
24、linux系统 /home目录下有一个文件test.xml,内容如下:

```
<configuration>
<artifactItems>
<artifactItem>
<groupId>zzz</groupId>
<artifactId>aaa</artifactId>
</artifactItem>
<artifactItem>
<groupId>xxx</groupId>
<artifactId>yyy</artifactId>
</artifactItem>
<!-- </artifactItem><groupId>some groupId</groupId>
<version>1.0.1.2.333.555</version> </artifactItem>-->
</artifactItems>
</configuration>
```
请写出shell脚本删除文件中的注释部分内容,获取文件中所有artifactItem的内容,并用如下格式逐行输出:
artifactItem:groupId:artifactId:aaa

bash 复制代码
#!/bin/bash


sed '/<!--.*-->/d' test.xml > test2.xml
egrep -n '<!--|\-\->' test2.xml |awk -F ':' '{print $1}' > /tmp/line_number1.txt
n=`wc -l /tmp/line_number1.txt|awk '{print $1}'`
n1=$[$n/2]
for i in `seq 1 $n1`
do
    j=$[$i*2]
    k=$[$j-1]
    x=`sed -n "$k"p /tmp/line_number1.txt`
    y=`sed -n "$j"p /tmp/line_number1.txt`
    sed -i "$x,$y"d test2.xml
done

grep -n 'artifactItem>' test2.xml |awk '{print $1}' |sed 's/://' > /tmp/line_number2.txt
n2=`wc -l /tmp/line_number2.txt|awk '{print $1}'`

get_value(){
    sed -n "$1,$2"p test2.xml|awk -F '<' '{print $2}'|awk -F '>' '{print $1,$2}' > /tmp/value.txt
    
    cat /tmp/value.txt|while read line
    do
        x=`echo $line|awk '{print $1}'`
        y=`echo $line|awk '{print $2}'`
        echo artifactItem:$x:$y
    done
}

n3=$[$n2/2]
for j in `seq 1 $n3`
do
    m1=$[$j*2-1]
    m2=$[$j*2]
    nu1=`sed -n "$m1"p /tmp/line_number2.txt`
    nu2=`sed -n "$m2"p /tmp/line_number2.txt`
    nu3=$[$nu1+1]
    nu4=$[$nu2-1]
    get_value $nu3 $nu4
done
25、请撰写一个shell函数,函数名为 f_judge,实现以下功能
  1. 当/home/log目录存在时将/home目录下所有tmp开头的文件或目录移到/home/log目录。

  2. 当/home/log目录不存在时,创建该目录,然后退出。

bash 复制代码
#!/bin/bash

f_judge()
{
    if [ -d /home/log ]
    then
	#find /home -name "tmp*" |xargs -i mv {} /home/log/
	find /home -name "tmp*" -exec mv {} /home/log/ \;
    else
	mkdir /home/log
	exit
    fi
}

f_judge
相关推荐
点亮一颗LED(从入门到放弃)2 小时前
字符设备驱动(5)
linux·运维·服务器
weixin_448119942 小时前
Datawhale 用Markdown语法轻松开发AI应用202512 第1次作业
运维·服务器
知识分享小能手2 小时前
CentOS Stream 9入门学习教程,从入门到精通,Linux日志分析工具及应用 —语法详解与实战案例(17)
linux·学习·centos
ZXF_H3 小时前
Linux tcpdump抓包实践(以http为例)
linux·http·wireshark·tcpdump
悄悄敲敲敲3 小时前
Linux:信号(二)
linux·操作系统·信号
Felven3 小时前
飞腾D2000 GPIO中断调试
linux·gpio·中断·d2000
西格电力科技3 小时前
面向工业用户的绿电直连架构适配技术:高可靠与高弹性的双重设计
大数据·服务器·人工智能·架构·能源
CodeCraft Studio3 小时前
用“录制宏”轻松实现文档自动化:ONLYOFFICE 宏功能实践解析
运维·自动化·onlyoffice·录制宏·创建宏·文档自动化·文档协同
喵了meme3 小时前
Linux学习日记21:读写锁
linux·c语言·学习