zoukankan      html  css  js  c++  java
  • shell 例子

    shell编程入门
    
    http://www.runoob.com/linux/linux-shell-variable.html
    
    http://c.biancheng.net/cpp/shell/
    
    1.查找当前目录中所有大于500M的文件,把这些文件名写到一个文本文件中,并统计其个数。
    find ./ -size +500M -type f | tee file_list | wc -l
    2.在目录/tmp下找到100个以abc开头的文件,然后把这些文件的第一行保存到文件new中。
    for filename in `find /tmp -type f -name "abc*"|head -n 100`
    do
    sed -n '1p' $filename>>new
    done
    3.把文件b中有的,但是文件a中没有的所有行,保存为文件c,并统计c的行数。
    grep -xvf a b | tee c | wc -l
    4.判断一文件是不是块或字符设备文件,如果是将其拷贝到 /dev 目录下
    read -p "input a file:" filename
    if [ -b $filename -o -c $filename ]
    then
        cp $filename /dev/
    fi
    5.每隔10分钟监控一次,监控/usr下如果大于5G,发邮件给管理员
    #!/bin/bash
    while true
    do
        sleep 600
        n=$(du -s /usr | cut -f1)
        if [ $n -gt 5242880 ]
        then
            mail -s "greater" filwsyl@gmail.com < ~/filename #将文件filename的内容发送出去。
        fi
    done
    6.从a.log文件中提取包含"WARNING""FATAL",同时不包含"IGNOR"的行,然后提取以":"分割的第5个字段
    grep -E 'WARNING|FATAL' a.log | grep -v IGNOR | awk -F ":" '{print $5}'
    7.编写一个脚本,进行简单的减法运算,要求提示输入变量
    #!/bin/bash
    read -p "input a number:" num1
    read -p "input another number:" num2
    let "num3=num1-num2"
    echo $num3
    8.把某个目录下的文件扩展名改为bat,再以时间为文件名压缩打包存放到某个目录。
    #!/bin/bash
    for file in $(ls $1)
    do
        new_file=${file%.*}.bat
        mv ./$1/$file ./$1/$new_file
        tmp=$(date +%y)
        tar cvf ./$tmp.tar ./$1
    done
    9.从网上下载一个文件,保存到指定目录
    #!/bin/bash
    url=http://rs1.bn.163.com/ent/2009/05/20_canquedege.wma
    dir=~/下载
    wget -P $dir $url
    10.判断一个数是不是完数。打印出1-1000之间的完数。完数就是约数的和等于自身2倍的数。(6,28,496)
    #!/bin/bash
    sub()
    {
        i=1;
        sum=0;
        while [ $i -le $num ]
        do
            let "m=num%i"
            if [ $m -eq 0 ]
            then
                let "sum=sum+i"
            fi
            let "i=i+1"
        done
        let "a=2*num"
        if [ $a -eq $sum ]
        then
            echo $num
        fi
    }
    num=1
    while [ $num -le 1000 ]
    do
        sub
        let "num = num+1"
    done
    11.以行为单位,求文件A和文件B交集,并集,差集。
    并:
    sort -m <(sort A | uniq) <(sort B | uniq) | uniq
    交:
    sort -m <(sort A | uniq) <(sort B | uniq) | uniq -d
    差:
    sort -m <(sort A | uniq) <(sort B | uniq) <(sort B | uniq) | uniq -u
    12.在某个文件夹下查找含有指定字符串的文件
    #!/bin/bash
    for file in $(ls $2)
    do
        bname=$(grep -l $1 $2/$file)
        basename $bname
    done
    调用方法:./tst 000 bash#在文件夹bash中查找含有“000”的文件。
    13.添加一个新组为class1,然后添加属于这个组的30个用户,用户名的形式为stdxx,其中xx从01到30。
    #!/bin/bash
    groupadd class1
    for i in {9901..9930}
    do
        xx=$(echo $i | sed 's/99//');
        useradd -g class1 std$xx -p ""
    done
    14.实现自动删除50个账号的功能。账号名为stud1至stud50
    #!/bin/bash
    i=0
    while [ i -le 50 ]
    do
       let i++
           userdel -r stud$i
    done
    15.某系统管理员需每天做一定的重复工作,请按照下列要求,编制一个解决方案:
    (1)在下午4 :50删除/abc目录下的全部子目录和全部文件;
    (2)从早8:00~下午6:00每小时读取/xyz目录下x1文件中每行第一个域的全部数据加入到/backup目录下的bak01.txt文件内;
    (3)每逢星期一下午5:50将/data目录下的所有目录和文件归档并压缩为文件:backup.tar.gz;
    (4)在下午5:55将IDE接口的CD-ROM卸载(假设:CD-ROM的设备名为hdc);
    (5)在早晨8:00前开机后启动。
    vim /etc/crontab 在里面增加下面内容:
    1)50 16 * * * root rm -rf /abc/* 2>&1 &
    2)00 8-18 * * * root cat /xyz/x1|awk '{print $1}' >> /backup/bak01.txt 2>&1 &
    3)50 17 * * 1 root cd /data;tar -zcvf backup.tar.gz * 2>&1 &
    4)55 17 * * * root umount /hdc 2>&1 &
    5)在早晨8:00前开机后启动 --> 这个我不是很明白它的意思,不知道是不是8点前开机就启动上面的设定,8点后才开机就不用启动的意思。姑且用下面这个命令吧。
    chkconfig --level 2345 crond on
    16.设计一个shell程序,在每月第一天备份并压缩/etc目录的所有内容,存放在/root/bak目录里,且文件名
    为如下形式yymmdd_etc,yy为年,mm为月,dd为日。Shell程序fileback存放在/usr/bin目录下。
    vim /usr/bin/fileback.sh
    #!/bin/bash
    #fileback.sh
    #file executable: chmod 755 fileback.sh
    PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
    export PATH
    filename=`date +%y%m%d`_etc.tar.gz
    cd /etc/
    tar -zcvf $filename *
    mv $filename /root/bak/
    ------------------------------------------------------
    vim /etc/crontab 加入
    * * 1 * * root ./fileback.sh &
    17.有一普通用户想在每周日凌晨零点零分定期备份/user/backup到/tmp目录下,该用户应如何做?
    首先说一下非root用户编写crontab文件的方法。
    一:
    [sword@localhost ~]$ vim cronfile
    [sword@localhost ~]$ crontab cronfile
    二:
    [sword@localhost ~]$ crontab -e
    no crontab for sword - using an empty one
    crontab: installing new crontab
    查看结果:
    [root@localhost cron]# crontab -u sword -l
    显示内容是:/var/spool/cron/sword 文件的内容。
    vim ~/shit.sh
    #!/bin/bash
    cp /user/backup/* /tmp/
    --------------------------------------------
    crontab -e
    0 0 * * 0 ~/shit.sh &
    18.设计一个Shell程序,在/userdata目录下建立50个目录,即user1~user50,并设置每个目录的权限,其
    中其他用户的权限为:读;文件所有者的权限为:读、写、执行;文件所有者所在组的权限为:读、执行。
    #!/bin/bash
    for ((i=1;i<=50;i++))
    do
           mkdir -p /usrdata/user$i
           cd /usrdata
           chmod 754 user$i
    done
    19.一个文件内容全部是类似
    【202.205.151.21】--【23:59:22】-“HTTP GET”-“Mozila”
    ...
    写一个SHELL命令找出最多的10个IP
    awk -F "--" '{print $1}' shit | sort | uniq -c | sort -r | sed -n '1,10p'
    20./tmp路径下有800个文件,文件名的格式是:filename_YYYYMMDD_序列号(从001到999).dat, 例如:filename_20040108_089.dat。现在想把这些文件改名,新文件名的格式是:filename_TODAY(当前日期)_序列号(从500开始,到达999之后从001开始).dat,例如: 把filename_20040108_089.dat改为filename_20041222_589.dat,注意新文件名的序列号的顺序需要和原来的一致,即要做排序处理。
    #!/usr/bin/bash
    DEST_FILE_PART2="_`date '+%Y%m%d'`_"
    EXT_NAME=".dat"
    SRC_FILE_LIST=`find /tmp -name "*_*_*$EXT_NAME" -print`
    for each in $SRC_FILE_LIST; do
        DEST_FILE_PART1=`echo $each | awk -F"_" '{print $1}'`
        OLD_NUM=`echo $each | awk -F"_" '{print $3}' | awk -F"." '{print $1}'`
        DEST_FILE_PART3=`expr $OLD_NUM + 500`
        [ $DEST_FILE_PART3 -gt 999 ] && DEST_FILE_PART3=`expr $OLD_NUM - 499`
            && DEST_FILE_PART3=`printf d $DEST_FILE_PART3`
        DEST_FILE=$DEST_FILE_PART1$DEST_FILE_PART2$DEST_FILE_PART3$EXT_NAME
        echo "mv $each to $DEST_FILE"
        mv $each $DEST_FILE
    done
    我的解法:
    #!/bin/bash
    new_file=$(date +20%y%m%d);
    for file in $(ls ~/bash)
    do
        i=$(echo "$file" | sed 's/.*_[0-9]*_([0-9]*).dat/1/')    #取出序列号
        i=$(echo $i | sed 's/^0*([0-9]*)/1/')                #去掉序列号前面可能的 ‘0’,
        let "ii=i+500"
        if [ $ii -gt 999 ]
        then
            let "ii=ii-999"
        fi
        ii=`printf d $ii`                            #添上可能需要的‘0’
        update=$(echo "$file" | sed 's/(.*)_[0-9]*_[0-9]*.dat/1_'$new_file'_'$ii'.dat/')
        mv ~/bash/$file ~/bash/$update
    done
    21.要求:在一个脚本中完成这个程序
    1.从文件user.list中取出已给定的用户名和用户组,将这些用户和组按规则添加到系统中
    2.从password.list中读取已经给定的用户密码。
    user.list如下
    zhangsan adminuser,dbuser,updatauser
    lisi dbuser,updatauser
    wanger updatauser,wheel
    
    #!/bin/bash
    #group add
    for x in ‘awk ‘{print $2}’ user.list | sed ’s/,/
    /g’ | sort | uniq -c|sed ’s/[^a-zA-Z]//g”
    do
            groupadd $x &> /dev/null
    done
    #back message
    if (($?==0))
    then
            echo “Group Ok!!”
    else
        exit 1
    fi
    #user add
    for i in ‘awk ‘{print $1}’ user.list’
    do
        for y in ‘awk ‘{print $2}’ password.list’
        do
        useradd $i &> /dev/null
        echo $y | passwd –stdin $i &> /dev/null
        done
    done
    #back message
    if (($?==0))
    then
        echo “User Ok!”
    else
        exit 1
    fi
    #add users to groups
    for ((q=1;q<=3;q++))
    do
        usermod -G ‘awk “NR==$q {print $2}” user.list | awk ‘{print $2}” ‘awk “NR==$q {print $1}” user.list | awk ‘{print $1}” &> /dev/null
    done
    if (($?==0))
    then
        echo “All Finished!”
    fi
    22.比较两个小数大小。
    awk -v num1=6.6 -v num2=5.5 'BEGIN{print(num1>num2)?"0":"1"}'
    echo "0.14 > 0.15" | bc
    expr 1.2 < 1.3
      
    
    24. Shell脚本阅读(解释下面执行的功能),请挑出下面程序或脚本中的错误,并说明错在哪里。
    
    #!/bin/bash
    
    #监控cpuser的point端口是否正常
    
    logname="/home/forum/log/lpointlog.wf"
    
    flagfile="/home/forum/log/lognum.txt"
    
    lodnum=sed -n "1,1 p"$flagfile
    
    newnum=wc -l ${logname}
    
    echo $newnum >$flagfile
    
    totalnum=expr $newnum -$oldnum
    
    tail -n $totalnum $logname |grep "POINT_THREAD WARNING"
    
    if [$?==0]
    
    then
    
       mail -s "cpuser point "端口异常,请处理!" test@aa.com</dev/null
    
    fi>
    
     
    
    命令行替换用反引号,if [$?==0] 应该写做if [ $?=0 ],用来判断上次命令是否执行成功;
    
    倒数第二行应该是>/dev/null,最后fi后面的>去掉。
    
     
    
    25. 设计一个shell程序,在每月第一天备份并压缩/etc目录的所有内容,存放在/root/bak目录里,且文件名为如下形式yymmdd_etc,yy为年,mm为月,dd为日。Shell程序fileback存放在/usr/bin目录下。
    参考答案:
    (1)编写shell程序fileback:
    #!/bin/sh
    DIRNAME=`ls /root | grep bak`
    if [ -z "$DIRNAME" ] ; then
    mkdir /root/bak
    cd /root/bak
    fi
    YY=`date +%y`
    MM=`date +%m`
    DD=`date +%d`
    BACKETC=$YY$MM$DD_etc.tar.gz
    tar zcvf $BACKETC /etc
    echo "fileback finished!"
    (2)编写任务定时器:
    echo "0 0 1 * * /bin/sh /usr/bin/fileback" >; /root/etcbakcron
    crontab /root/etcbakcron
    或使用crontab -e 命令添加定时任务:
    0 1 * * * /bin/sh /usr/bin/fileback
    
    
    26. 有10台被监控主机,一台监控机,在监控机上编写脚本,一旦某台监控机器/分区使用率大于80%,就发出报警,放到crontab里面,每10分钟检查一次。
    
    (1)首先,建立信任关系 1 VS 10. 但拿两台机器(192.168.1.6,192.168.1.4)做试验
    
    #ssh-keggen -b 1024 -t rsa  //(以root用户)
    
    #cd .ssh/
    
    #ls
    
    id_rsa
    
    id_rsa.pub
    
    knows_host
    
    #scp id_rsa.pub 192.168.1.4:/root/.ssh/192.168.1.6
    
    这里把公钥取名为可信任主机的IP地址
    
    现在登录到192.168.1.4机器
    
    #cd .ssh/
    
    #cat 192.168.1.6 >> authorized_keys
    
    然后回到192.168.1.6机器。
    
    #ssh 192.168.1.4
    
    这样就可以了,里面可能涉及到权限问题。一般.ssh/文件夹为755,authorized_keys 600或644
    
    (2)脚本如下:
    
    #!/bin/sh
    
    #script:df_check.sh
    
    FSMAX="80"
    
    remote_user='root'
    
    remote_ip=(192.168.1.2 192.168.1.3 192.168.1.4 .......)   //十个ip地址
    
    ip_num='0'
    
    while [ "$ip_num" -le "$(expr ${#remote_ip[@]} - 1)" ]
    
    do
    
    read_num='1'
    
    ssh "$remote_user"@"${remote_ip[$ip_num]}" df -h >/tmp/diskcheck_tmp
    
    grep '^/dev/*' /tmp/diskcheck_tmp|awk '{print $5}'|sed 's/\%//g' >
    
    /tmp/diskcheck_tmp_num
    
    while [ "$read_num" -le $(wc -l < /tmp/diskcheck_tmp_num)] //计算有多少行
    
    do
    
    size=$(sed -n "$read_num"'p' /tmp/diskcheck_tmp_num)
    
    if [ "$size" -gt "$FSMAX" ]
    
    then
    
    $(grep '^/dev/*' /tmp/diskcheck_tmp|sed -n $read_num'p' >
    
    /tmp/disk_mail)
    
    $(echo $(remote_ip[$ip_num]) >> /tmp/disk_mail)
    
    $(mail -s "diskcheck_alert" admin </tmp/disk_mail)
    
    fi
    
    read_num=$(expr $read_num + 1)
    
    done
    
    ip_num=$(expr $ip_num + 1)
    
    done
    
    (3)放在crontab里面
    
    #######################################################################
    
    ################让脚本每十分钟执行一次#################################
    
    在cron表中:
    
    0/10 * * * * /home/codefei/diskcheck.sh 2>&1
    
     
    
    27. 用Shell编程,判断一文件是不是字符设备文件,如果是将其拷贝到 /dev 目录下。
    参考程序:
    #!/bin/sh
    FILENAME=
    echo “Input file name:”
    read FILENAME
    if [ -c "$FILENAME" ]
    then
    
    cp $FILENAME /dev
    fi
  • 相关阅读:
    整数的二进制表示中1的个数
    最长公共子序列
    关于使浏览器崩溃的代码尝试
    wp7 独立存储
    动态引用样式表
    锋利的jQuery小记……
    DataGridVidw添加CheckBox。并通过一个 CheckBox来控制其全选。
    全选按钮的使用。winfrom程序中,对全选按钮的理解,欢迎拍砖!
    Ul li 超出文本显示省略号JS右键控制 本人QQ:267307031 空间更多技术咨询
    FileUpload控件
  • 原文地址:https://www.cnblogs.com/xiaohuamao/p/10118490.html
Copyright © 2011-2022 走看看