shell实例100例《十》

91、题目要求   : 部署MySQL主从

用shell脚本实现,部署mysql主从,假设两台机器上已经安装了mysql,并且目前无新库。
 

【核心要点】

步骤 : 1、主上改配置文件,打开bin-log,设定server_id ,设定ignore_db ,重启,授权用户,锁表,show master staus .

2、从上改配置文件,设定server_id,重启,stop slave ,chang master ,start slave。

在主上写一个脚本,所有操作在此脚本完成,包括写expect脚本和执行expect脚本。

参考答案
#!/bin/bash
#这个脚本用来配置MySQL主从同步
#作者:猿课-阿铭 www.apelearn.com
#日期:2018-12-17

#!/bin/bash
master_ip=192.168.100.12
slave_ip=192.168.100.13
mysqlc="mysql -uroot -paminglinux"

check_ok()
{
    if [ $? -ne 0 ]
    then
        echo "$1 出错了。"
        exit 1
    fi
}

f_exist()
{
    d=`date +%F%T`
    if [ -f $1 ]
    then
        mv $1 $1_$d
    fi
}

## 设置主mysql配置
if ! grep '^server-id' /etc/my.cnf
then
    sed -i '/^\[mysqld\]$/a\server-id = 1001' /etc/my.cnf
fi

if ! grep '^log-bin.*=.*' /etc/my.cnf
then
    sed -i '/^\[mysqld\]$/a\log-bin = aminglinux' /etc/my.cnf
fi

sed -i '/^log-bin.*/a\binlog-ignore-db = mysql ' /etc/my.cnf

/etc/init.d/mysqld restart
check_ok "主上重启mysql"

## 登录mysql,授权用户、锁表以及show master status。
$mysqlc <<EOF
    grant replication slave on *.* to 'repl'@$slave_ip identified by 'yourpassword';
    flush tables with read lock;
EOF
$mysqlc -e "show master status" > /tmp/master.log
file=`tail -1 /tmp/master.log|awk '{print $1}'`
pos=`tail -1 /tmp/master.log|awk '{print $2}'`

## 创建在从上配置和操作的脚本
f_exist /tmp/slave.sh

cat > /tmp/slave.sh << EOF
#!/bin/bash
if ! grep '^server-id' /etc/my.cnf
then
    sed -i '/^\[mysqld\]$/a\server-id = 1002' /etc/my.cnf
fi

/etc/init.d/mysqld restart
check_ok "从上重启mysql"

$mysqlc  <<EOF
    stop slave;
    change master to master_host="$master_ip", master_user="repl", master_password="yourpassword", master_log_file="$file", master_log_pos=$pos;
    start slave;
EOF 
EOF

## 创建传输slave.sh的expect脚本
f_exist /tmp/rs_slave.expect

cat > /tmp/rs_slave.expect <<EOF
#!/usr/bin/expect
set passwd "aminglinux"
spawn rsync -a /tmp/slave.sh root@$slave_ip:/tmp/slave.sh
expect {
    "yes/no" { send "yes\r"}
    "password:" { send "\$passwd\r" }
}
expect eof
EOF

## 执行expect脚本
chmod +x /tmp/rs_slave.expect
/tmp/rs_slave.expect
check_ok "传输slave.sh"

## 创建远程执行命令的expect脚本
f_exist /tmp/exe.expect

cat > /tmp/exe.expect <<EOF
#!/usr/bin/expect
set passwd "aminglinux"
spawn ssh root@$slave_ip
expect {
    "yes/no" { send "yes\r"}
    "password:" { send "\$passwd\r" }
}
expect "]*"
send "/bin/bash /tmp/slave.sh\r"
expect "]*"
send "exit\r"
EOF

## 执行expect脚本
chmod +x /tmp/exe.expect
/tmp/exe.expect
check_ok "远程执行slave.sh"

## 主上解锁表
$mysqlc -e "unlock tables"

实例 :

在/etc/my.cnf文件中,添加server-id

38a87bade89ad487c3cbdc5e141c9a60930.jpg

8a84eeda043ecb77508c226feda7fd6a969.jpg

 

执行脚本,查看结果

注意  : 

if [ $? -ne 0 ]                                          #$?等于0

 

if ! grep '^server-id' /etc/my.cnf                       #在/etc/my.cnf文件中查看有没有server-id,如果没有,执行下一步。

sed -i '/^\[mysqld\]$/a\server-id = 1001' /etc/my.cnf                #/etc/my.cnf文件中查看没有server-id,就在/etc/my.cnf 中添加。 

 

sed -i '/^\[mysqld\]$/a\log-bin = aminglinux' /etc/my.cnf                          #

sed -i '/^log-bin.*/a\binlog-ignore-db = mysql ' /etc/my.cnf                            #添加一个忽略的数据库叫MySQL,不做同步。

sed -i '/^\[mysqld\]$/a\server-id = 1002' /etc/my.cnf                       #将server-id = 1002,输入到/etc/my.cnf  。

$mysqlc -e "show master status" > /tmp/master.log                          #show master statu的结果,输出到 /tmp/master.log   。

 

EOF                                     #是用在mysqlc
EOF                                     #是用在cat > /tmp/slave.sh << EOF

spawn rsync -a /tmp/slave.sh root@$slave_ip:/tmp/slave.sh                    #将/tmp/slave.sh传输到root@$slave_ip:/tmp/slave.sh 

如果系统是CentOS 7,而且使用的yum安装的MySQL,重启命令可能要使用  : systemctl restart mysqld

 

 

92、题目要求   :  管理docker

写一个脚本,实现一键管理docker容器,比如启动、关闭、删除容器等操作。 要求:

  1. 脚本支持启动全部容器、关闭全部容器、删除全部容器
  2. 需要提示用户如何使用该脚本,需给出范例

【核心要点】

1、要关闭或启动容器,首先要知道容器的id,使用命令docker ps -a 查看,第一列就是容器id。

2、需要以交互的方式让用户输入关闭、启动或者删除的命令,如果用户输入的命令不对需要给出提示。

3、可以把容器的id先存入到一个临时文件里,方便后续遍历。

参考答案
#!/bin/bash
#这个脚本用来管理docker容器
#作者:猿课-阿铭 www.apelearn.com
#日期:2018-12-17

while true
do
    read -p "请输入你要执行的操作:(stop/start/rm) " opt
    if [ -z "$opt" ]
    then
        echo "请输入要执行的操作。"
        continue
    else
        break
    fi
done

docker ps -a |awk '{print $1}' > /tmp/id.txt
case $opt in
  stop)
    for id in `cat /tmp/id.txt`
    do
        docker stop $id
    done
    ;;
  start)
    for id in `cat /tmp/id.txt`
    do
        docker start $id
    done
  rm)
    for id in `cat /tmp/id.txt`
    do
        read -p "将要删除容器$id,是否继续?(y|n)" c
        case $c in
          y|Y)
            docker rm -f $id
            ;;
          n|N)
            echo "容器$id不会被删除。"
            ;;
          *)
            echo "你只能输入'y'或者'n'。"
            ;;
        esac
    done
  *)
    echo "你只能输入start/stop/rm。"
    ;;
esac

 

注意  : 

docker ps -a |awk '{print $1}' > /tmp/id.txt                     # 把所有的容器的id,写入到/tmp/id.txt 

for id in `cat /tmp/id.txt`                            # 在 /tmp/id.txt,查看容器的ID。

 

 

93、题目要求   : 安装配置samba

写个shell脚本,能够实现一键安装并配置samba服务,执行该脚本时需要带一个参数,为共享的目录,目录若不存在,需自动创建。

要求,任何人都可以访问,且不用密码,并且目录是只读的。

【核心要点】

1、需要判断用户给出的目录是不是绝对路径,即是否是'/'开头

2、脚本要判断samba服务是否已经安装,若已经安装了就不需要执行yum install samba了

参考答案
#!/bin/bash
#这个脚本用来一键安装并配置samba
#作者:猿课-阿铭 www.apelearn.com
#日期:2018-12-17

if [ "$#" -ne 1 ]
then
    echo "运行脚本的格式为:$0 /dir/"
    exit 1
else
    if ! echo $1 |grep -q '^/.*'
    then
        echo "请提供一个绝对路径。"
        exit 1
    fi
fi

if ! rpm -q samba >/dev/null
then
    echo "将要安装samba"
    sleep 1
    yum install -y samba
    if [ $? -ne 0 ]
    then
        echo "samba安装失败"
        exit 1
    fi
fi

cnfdir="/etc/samba/smb.conf"
cat >> $cnfdir <<EOF
[share]
        comment = share all
        path = $1
        browseable = yes
        public = yes
        writable = no
EOF

if [ ! -d $1 ]
then
    mkdir -p $1
fi

chmod 777 $1
echo "test" > $1/test.txt

#假设系统为CentOS7
systemctl start smb
if [ $? -ne 0 ]
then
    echo "samba服务启动失败,请检查配置文件是否正确。"
else
    echo "samba配置完毕,请验证。"
fi

实例 :

执行脚本,查看结果

注意  : 

if ! echo $1 |grep -q '^/.*'                                  #如果不是/开头,就提示用户提供一个绝对路径。

if [ $? -ne 0 ]                             # 当$?不等于0,提示安装失败了。

cat >> $cnfdir <<EOF                                         #追加几行下面的内容

[share]                                               #模块的名字 [share]

comment = share all                                     #comment(描述)
path = $1                                                #    共享的目录路径        
browseable = yes                                      #是不是可见的
public = yes                                     #是不是公开的,意思是不需要密码认证。
writable = no                                     #是不是可写的

 

if [ ! -d $1 ]                                 #判断目录是否存在。

echo "test" > $1/test.txt                            #在$1下,创建一个文件test.txt 

 

94、题目要求   :   批量查看堕胎机器负载

假如公司的一个业务,域名为www.aminglinux.com,现在有5台机器在跑。为了快速查看这5台机器的负载,需要你写一个Shell脚本,运行脚本后,就能一下子把5台机器的负载全部打印出来。

【核心要点】

expect脚本或者配置密钥认证

ssh-keygen -f /root/.ssh/newkey           #把公钥拷贝到,对方的文件的目录下 ;-f指定目录的名字

ssh -i /root/.ssh/newkey ip                    #指定私钥的位置。

ssh-agent                          #把私钥搞到内存里面

ssh-add /root/.ssh/newkey          #把密钥添加到内存中。

eval ‘ssh-agent’               #

参考答案
#!/bin/bash
#这个脚本用来批量查机器负载
#作者:猿课-阿铭 www.apelearn.com
#日期:2018-12-17

for ip in `cat /tmp/ip.list`
do
    echo $ip 
    ssh $ip "uptime"
done

实例 :

把密钥写到/tmp/aaa文件中

7c103456989c15d73e9aeaf3eff91f6cf5c.jpg

ls /tmp/查看生成的密钥,aaa是私钥,aaa.pub是公钥

595359de888c3ca0236cc2afa32b73be22e.jpg

7c2de4548de431aa27fa2b3d3e8a58430cb.jpg

8524a18812951b2e2431c63c6ca217f1e7c.jpg

测试,查看拷贝的密钥,第一次登录127.0.0.1,有没有生效。

6cd49250f4869d063ec4389a95801490ee6.jpg

如果出现下面的提示,说明没有添加成功,密钥生效,就把cat /tmp/aaa.pub中的公密钥写入到vi /root/.ssh/authorized_keys。再次执行ssh -i /tmp/aaa root@127.0.0.1

a29c52d6aec8dca6b506a037067b086caa2.jpg

第二次登录127.0.0.1的效果。

88b20ad69b6f1a5a6fa2e255fc2604211dd.jpg

ssh-agent把私钥搞到内存里面

9aa9a78b6d483668d1e2f7c4fc6c5bfac94.jpg

cee4e291b74a0199ab9ef14310d6c0735d1.jpg

再次执行发现就不用,密码登录了。

75cbedae983d9854587e08ae165020db989.jpg

执行脚本,查看结果

 

注意  : 

 

 

95、题目要求    :   自动挂云盘

我们使用的云主机,购买一块云盘后,默认并不是挂载状态的,用shell写一个脚本,只要把盘符和挂载点以参数的形式提供给脚本,该脚本就可以自动格式化、挂载。

要求:

  1. 不用分区,直接格式化
  2. 格式化为ext4文件系统类型

【核心要点】

1、参数要有两个,第一个是设备名,第二个是挂载点,需要判断给出的参数个数以及是否可用

2、格式化磁盘的命令为mkfs.ext4磁盘设备名。

3、mount命令挂载,挂载完后还需要编辑/etc/fstab配置文件

参考答案
#!/bin/bash
#这个脚本用来自动挂载磁盘
#作者:猿课-阿铭 www.apelearn.com
#日期:2018-12-17

if [ $# -ne 2 ]
then
    echo "Useage $0 盘符 挂载点, 如: $0 /dev/xvdb /data"
    exit 1
fi

if [ ! -b $1 ]
then
    echo "你提供的盘符不正确,请检查后再操作"
    exit 1
fi

echo "格式化$1"
mkfs -t ext4 $1

if [ ! -d $2 ] ;then
        mkdir -p $2
fi

n=`awk '$NF == "$2"' /etc/fstab|wc -l`
if [ $n -eq 0 ]
then
    echo "$1              $2                      ext4   defaults  0  0" >> /etc/fstab
    mount -a
else
    echo "配置文件/etc/fstab中已经存在挂载点$2,请检查一下."
    exit 1
fi

实例 :

执行脚本,查看结果

注意  : 

 

 

96、题目要求    :    并发备份数据库

需求背景:

领导要求小明备份数据库服务器里面的100个库(数据量在几十到几百G),需要以最快的时间完成(5小时内),并且不能影响服务器性能。

【核心要点】

通过命名管道FIFO来实现
参考答案
#!/bin/bash
#这个脚本用来并发备份数据库
#作者:猿课-阿铭 www.apelearn.com
#日期:2018-12-19

##假设100个库的库名、host、port以及配置文件路径存到了一个文件里,文件名字为/tmp/databases.list
##格式:db1 10.10.10.2 3308 /data/mysql/db1/my.cnf
##备份数据库使用xtrabackup(由于涉及到myisam,命令为inoobackupex)

exec &> /tmp/mysql_bak.log

if ! which innobackupex &>/dev/nll
then
    echo "安装xtrabackup工具"
    rpm -ivh http://www.percona.com/downloads/percona-release/redhat/0.1-3/percona-release-0.1-3.noarch.rpm  && \ 
    yum install -y percona-xtrabackup-24
    if [ $? -ne 0 ]
    then
        echo "安装xtrabackup工具出错,请检查。"
        exit 1
    fi
fi

bakdir=/data/backup/mysql
bakuser=vyNctM
bakpass=99omeaBHh

function bak_data {
    db_name=$1
    db_host=$2
    db_port=$3
    cnf=$4
    [ -d $bakdir/$db_name ] || mkdir -p $bakdir/$db_name
    innobackupex --defaults-file=$4  --host=$2  --port=$3 --user=$bakuser --password=$bakpass  $bakdir/$1
        if [ $? -ne 0 ]
        then
            echo "备份数据库$1出现问题。"
        fi
}

fifofile=/tmp/$$
mkfifo $fifofile
exec 1000<>$fifofile


thread=10
for ((i=0;i<$thread;i++))
do
    echo >&1000
done

cat /tmp/databases.list | while read line
do
    #每循环一次,读一次fd100中的内容,即空行,只有读到空行了才会执行{}内的指令
    #每次循环都需要打印当前的时间,休眠1秒,然后再次向fd100中写入空行,这样后续的read就有内容了
    #
    read -u1000
    {
        bak_data `echo $line`
        echo >&1000
    } &  //丢到后台去,这样10次很快就循环完,只不过这些任务是在后台跑着,由于我们一开始就向fd1000里写入了两个空行,所以read会一次性读到两行。
done
#等待所有后台任务执行完成
wait
#删除fd1000
exec 1000>&-
#删除命名管道
rm -f $fifofile

实例 :

安装一个窗口screen , 直接输入”screen“命令就进入了另一个窗口

f0e75deed0cd534c6874d98eb5fa02e9cc9.jpg

f683abe8c92f64aac16b95c1c7ee4fd84dc.jpg

使用mkfifo命令,创建一个管道文件1.fifo。

67e8cbceeda1b2f9b3382e8de4d8f22c84f.jpg

往管道里面写入东西,出现卡顿现象,原因:只写入东西,没有进程读它。先使用"cat 1.fifo"读取新建的管道文件,然后再写入东西。(ctrl +a 退出screen窗口)

85ce9cadc51f9216ce4e874a50defef3d75.jpg

把100个文件流绑定再一起,并查看结果,生成的结果是一个软链接。

d928e225a968bf0246c42d91e0f2de27dc9.jpg

读100个用户,并赋值给a。

ca2c0e281c1c7934672c10dd41d586f1b15.jpg

 

注意  : 

exec &> /tmp/mysql_bak.log                   #定义一个/tmp/mysql_bak.log ,所有的命令、结果写入到这个日志里面

if ! which innobackupex &>/dev/nll                   # 检测innobackupex命令是否存在

function bak_data {                            #定义备份数据库的函数,用于备份数据库

 

 innobackupex --defaults-file=$4  --host=$2  --port=$3 --user=$bakuser --password=$bakpass  $bakdir/$1            #备份数据库,$4指定配置文件的路径等等,然后放到 $bakdir/$1 

 

if [ $? -ne 0 ]           #返回值不等于0,就提示用户。

fifofile=/tmp/$$                          #fifo文件的定义
mkfifo $fifofile                        #创建匿名管道文件
exec 1000<>$fifofile                      #把100个文件流绑定再一起。

 

thread=10                                    #定义并发量为10

 echo >&1000                     #写入10次

cat /tmp/databases.list | while read line                   #有几个数据库的列表,就循环几次。

 

97、题目要求   :   打印三角形

之前咱们打印过正方形,也打印过乘法口诀,那今天来打印一个三角形(正三角形,元素用*表示)。

【核心要点】

正三角形的元素排列,如果边长为5个* ,在shell终端显示该正三角形的话,需要有5行,第一行应该先打印4个空格,然后再打印'*',第二行先打印3个空格,然后打印‘*’ ,一直到第5行打印0个空格。

参考答案
#!/bin/bash
#这个脚本用来打印三角形
#作者:猿课-阿铭 www.apelearn.com
#日期:2018-12-19

while true
do
    read -p "please input the lenth: " n
    if [ -z $n ]
    then
        echo "要输入一个数字。"
        continue
    else
        n1=`echo $n|sed 's/[0-9]//g'`
        if [ -n "$n1" ]
        then
            echo "你输入的不是纯数字,重新输入。"
            continue
        else
            break
        fi
    fi
done

for i in `seq 1 $n`
do
    j=$[$n-$i]
    for m in `seq $j`
    do
        echo -n " "
    done

    for p in `seq 1 $i`
    do
        echo -n "* "
    done
    echo
done

实例 :

 

 

执行脚本,输入执行三角形的边长为几,查看结果。

f0d98066559f88f00070f13ff87430686e9.jpg

注意  : 

if [ -z $n ]                             #$n为空,提示用户。

n1=`echo $n|sed 's/[0-9]//g'`                             #判断用户输入的,是不是数字。

if [ -n "$n1" ]                             #如果不是数字。就提示用户。是数字就退出。

 

for i in `seq 1 $n`                   #循环次数是1到$n.

j=$[$n-$i]                   #第一次打印的空格次数吗,j是要打印空格的次数。

 

 

98、题目要求   :    截取字符串

利用你学过的知识点,想办法根据要求。

字符串var=http://www.aaa.com/root/123.htm

1.取出www.aaa.com/root/123.htm

2.取出123.htm

3.取出http://www.aaa.com/root

4.取出http:

5.取出http://

6.取出root/123.htm

7.取出123

【核心要点】

grep/sed/awk

参考答案
#!/bin/bash
#这个脚本用来截取字符串
#作者:猿课-阿铭 www.apelearn.com
#日期:2018-12-19
var=http://www.aaa.com/root/123.htm
echo "1.取出www.aaa.com/root/123.htm"
echo $var |awk -F '//' '{print $2}'

echo "2.取出123.htm"
echo $var |awk -F '/' '{print $5}'

echo "3.取出http://www.aaa.com/root"
echo $var |sed 's#/123.htm##'

echo "4.取出http:"
echo $var |awk -F '//' '{print $1}'

echo "5.取出http://"
echo $var |awk -F 'www' '{print $1}'

echo "6.取出root/123.htm"
echo $var |awk -F 'com/' '{print $2}'
echo $var |awk -F '/' '{print $4"/"$5}'

echo "7.取出123"
echo $var |sed 's/[^0-9]//g'

实例 :

使用awk命令截取出www.aaa.com/root/123.htm

eee8fbbedeaa56fa7d040601e588c92bee2.jpg

使用sed命令截取出第二段字符

581bd59c3184120dd582c94c916a3223c52.jpg

使用awk命令截取出取出123.htm、取出http://www.aaa.com/root、取出http:、取出http://、取出root/123.htm、取出123。-F表示以什么做空格、间隔符,

0364ad280b0e52f9b158480cd3b1d0453ba.jpg

执行脚本,查看结果

f7a269e466c7891df81e57696d5fb64f4a3.jpg

 

 

99、题目要求   :    修改文本格式

请把下面的字符串写入到test3.txt文档中:

zhangsan
y97JbzPru
lisi
5JhvCls6q
xiaowang
Nnr8qt2Ma
laoma
iqMtvC02y
zhaosi
9fxrb4sJD

改为如下:

zhangsan:y97JbzPru
lisi:5JhvCls6q
xiaowang:Nnr8qt2Ma
laoma:iqMtvC02y
zhaosi:9fxrb4sJD

【核心要点】

奇数、偶数行

参考答案
#!/bin/bash
#这个脚本用来格式化文本
#作者:猿课-阿铭 www.apelearn.com
#日期:2018-12-19

n=`wc -l test3.txt|awk '{print $1}'`
n2=$[$n/2]

for i in `seq 1 $n2`
do
    i2=$[$i*2]
    j=$[$i2-1]
    l1=`sed -n "$i2"p test3.txt`
    l2=`sed -n "$j"p test3.txt`
    echo $l2:$l1
done

实例 :

把第一行的第二行的换行符换成冒号。;s表示替换,N表示 把第一二变成一行; \n表示 表示替换; :/ :把换行符换成冒号。

aec2f5f6be0aae36c22a9e5da940b228c1c.jpg

86482513256f508d09b315f89f8c373d814.jpg

执行脚本,查看结果

fbdf230f71a38e6dc9c06e343adbe980c57.jpg

注意  : 

n=`wc -l test3.txt|awk '{print $1}'`                                       #统计文档中的行数。并打印出一行
n2=$[$n/2]                                       #把第二行,合并成一行

for i in `seq 1 $n2`                                       #执行的行数是1到$n2
i2=$[$i*2]                                       #i2表示 ,需要要换行的次数
j=$[$i2-1]                                       #j表示 ,循环的次数
l1=`sed -n "$i2"p test3.txt`                                       #l1表示奇数行的内容,
l2=`sed -n "$j"p test3.txt`                                       #l2表示偶数行的内容,
echo $l2:$l1                                       #$l2:$l1 表示偶数行、奇数行合并的行数

 

100、题目要求   :    自定义rm

inux系统的rm命令太危险,一不小心就会删除掉系统文件。 写一个shell脚本来奇数行的,要求当删除一个文件或者目录时,都要做一个备份,然后再删除。下面分两种情况,做练习:

  1. 简单

假设有一个大的分区/data/,每次删除文件或者目录之前,都要先在/data/下面创建一个隐藏目录以日期/时间命名,比如/data/.201703271012/,然后把所有删除的文件同步到该目录下面,可以使用rsync -R 把文件路径一起同步

  1. 复杂

不知道哪个分区有剩余空间,在删除之前先计算要删除的文件或者目录大小,然后对比系统的磁盘空间,如果够则按照上面的规则创建隐藏目录,并备份,如果没有足够空间,要提醒用户没有足够 的空间备份并提示是否放弃备份,如果用户选择y,则直接删除文件或者目录,如果选择n,则提示未删除,然后退出脚本。

【核心要点】

参考答案
1. 简单
#!/bin/bash
#这个脚本用来自定义rm
#作者:猿课-阿铭 www.apelearn.com
#日期:2018-12-19

filename=$1
big_filesystem=/data/

if [ ! -e $1 ]
then
    echo "$1 不存在,请使用绝对路径"
    exit
fi
d=`date +%Y%m%d%H%M`
read -p "Are U sure delete the file or directory $1? y|n: " c
case $c in 
      y|Y)
          mkdir -p $big_filesystem/.$d && rsync -aR $1 $big_filesystem/.$d/$1 && /bin/rm -rf $1
          ;;
      n|N)
          exit 0
          ;;
      *)
          echo "Please input 'y' or 'n'."
          ;;
esac

2.复杂
#!/bin/bash
#这个脚本用来自定义rm
#作者:猿课-阿铭 www.apelearn.com
#日期:2018-12-19

#!/bin/bash
filename=$1

if [ ! -e $1 ]
then
    echo "$1 不存在,请使用绝对路径"
    exit
fi
d=`date +%Y%m%d%H%M`
f_size=`du -sk $1|awk '{print $1}'`
disk_size=`LANG=en; df -k |grep -vi filesystem|awk '{print $4}' |sort -n |tail -n1`
big_filesystem=`LANG=en; df -k |grep -vi filesystem |sort -n -k4 |tail -n1 |awk '{print $NF}'`

if [ $f_size -lt $disk_size ]
then
    read -p "Are U sure delete the file or directory: $1? y|n: " c
    case $c in 
      y|Y)
          mkdir -p $big_filesystem/.$d && rsync -aR $1 $big_filesystem/.$d/$1 && /bin/rm -rf $1
          ;;
      n|N)
          exit 0
          ;;
      *)
          echo "Please input 'y' or 'n'."
          ;;
     esac
else
    echo "The disk size is not enough to backup the files $1."
    read -p "Do you want to delete $1? y|n: " c
    case $c in
      y|Y)
        echo "It will delete $1 after 5 seconds whitout backup."
        for i in `seq 1 5`; do echo -ne ". "; sleep 1;done
        echo
        /bin/rm -rf $1
        ;;
     n|N)
        echo "It will not delete $1."
        exit 0
        ;;
      *)
        echo "Please input 'y' or 'n'."
        ;;
    esac
fi

实例 :

查看磁盘的使用率

073c0271f9adcab8ecfa9942e0cf5d8cceb.jpg

执行脚本,查看结果

fc3e7120b9d0683168d4358107a6c57ce36.jpg

注意  : 

if [ ! -e $1                       #如果提供的路径不存在,就提示用户。

mkdir -p $big_filesystem/.$d && rsync -aR $1 $big_filesystem/.$d/$1 && /bin/rm -rf $1                             #创建隐藏的目录,并备份隐藏的目录,同步完了,再删除 。-R:把目录的结果一起同步过去。

 

f_size=`du -sk $1|awk '{print $1}'`                            #判断要删除的文件的大小
disk_size=`LANG=en; df -k |grep -vi filesystem|awk '{print $4}' |sort -n |tail -n1`                             #
big_filesystem=`LANG=en; df -k |grep -vi filesystem |sort -n -k4 |tail -n1 |awk '{print $NF}'`                             #查看最大的分区答空间大小,并显示出来。

 

if [ $f_size -lt $disk_size ]                            #要删除的文件的大小小于磁盘空间,就可以删除了。

$big_filesystem/.$d && rsync -aR $1 $big_filesystem/.$d/$1 && /bin/rm -rf $1                               #备份删除的文件的,然后删除。

 

for i in `seq 1 5`; do echo -ne ". "; sleep 1;done              #停顿5秒,每停顿那一秒,就打印一个点。

 

如果发生误删的操作,马上停止所有的写的操作,那么找回来的机会比较答。

 

来源 : https://github.com/aminglinux/shell100/blob/master/61.md

转载于:https://my.oschina.net/u/3803405/blog/3008429

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值