数码之家

 找回密码
 立即注册

QQ登录

只需一步,快速开始

微信登录

微信扫一扫,快速登录

搜索
查看: 1782|回复: 6

[软件] 血得教训!给rm命令起别名避免痛不欲生...

[复制链接]
发表于 2021-12-16 10:49:01 | 显示全部楼层 |阅读模式

爱科技、爱创意、爱折腾、爱极致,我们都是技术控

您需要 登录 才可以下载或查看,没有账号?立即注册 微信登录

x
背景
楼主用docker挂载代码目录做开发,会把本机一些配置文件、smb目录也挂进去便于构造开发环境。
由于项目分枝众多,经常需要建立、删除容器来构造环境。
为了在新建docker容器前把该建立的、布置的东西都自动化(懒),写个脚本执行各种命令。

过程
最近对docker又鼓捣了鼓捣,想把镜像里的用户家目录给移出来,把各种配置文件都换成软链接,例如
.gitconfig ->  /host/gitconfig
这样把本地目录挂载镜像的/host就可以直接使用文件了(避免-v 文件导致不能即使感知文件变化和反复重建镜像)
挂载后启动发现容器里的提示符光秃秃的,变成
-bash-4.2$
正常应该是
[用户名@主机名 当前目录]$
楼主还在PS1里加了git插件来显示分枝,没了很不爽
原因很简单:家目录下的.bashrc用于引导bash去读取/etc/bashrc
没了只能用默认值,我挂进去的家目录啥都没有。
解决方法也懒:从正常镜像里拷贝出个家目录当模板,每次构筑容器前,
建立个新目录并把模板里的各种文件拷贝过去。

悲剧
拷贝后启动发现还是"光棍儿"提示符,ls -a 发现正常文件都拷贝了,而隐藏文件没有
拷贝,linux下隐藏文件是.开头的,例如.bashrc
脚本里写得是
cp -a user_home/* abc.local/user_home/
这样不会拷贝.文件
于是......想当然的就写成
cp -a user_home/.* abc.local/user_home/

拷贝速度贼慢,很奇怪...启动容器,热闹了后发现家目录下什么文件都有,乱七八糟的...............

原因
.*会匹配到..然后 -a隐含了-r做递归,于是...就递归向上拷贝咯

大悲剧
先抽了自己几嘴巴子,然后在宿主机后执行了
rm -rf abc.local/user_home/*

速度又异常慢.....

蹲个坑后回来后感觉不对....

没关闭额的vscode一片红色删除线(文件被删除)????并且所有导航
功能不能操作(我是vscode远程到linux机做开发)
windows机上资源管理器一刷新,windows共享的目录下东西也干净了


一个rm命令,把挂载目录、宿主机用户家目录、代码全部干掉!

不对?我是删除得拷贝后文件,怎么连同原文件一起没了?

原因是...这个目录正被docker挂载了,它把被挂载目录的fd(我的软链接)变成真实目录的fd
则我rm目录,变成对真实目录rm.......


血得教训!千万不要在宿主机对一个还在打开中的容器挂载目录进行rm操作.......

后记
数据恢复做了,但没啥意义。代码损失一个分枝,幸好没啥提交值得留念,不要了。
多年积累的压缩包没了,恢复后不敢用,放弃........

补救
写个脚本代替rm,实现windows上回收站功能,以免痛不欲生
当然有现成的工具,例如trash-cli,但自己挑战性最好

加在/etc/bashrc里
#只有"人"操作才用这个,后台登录进程继续用原生的rm
[[ $- != *i* ]] && return
if [ ! -f "/opt/.trushbin" ]; then
    sudo mkdir -p "/opt/.trushbin"
    #给垃圾桶设置特权位(1000)保持文件所有者
    sudo chmod 1777 "/opt/.trushbin"
fi
export trushbin="/opt/.trushbin"
function put_into_trushbin()
{
    if [ -z ${trushbin} ]; then
        \rm $@
        return
    fi
    filenames=()
    for i in "$@";
    do
        #区分参数和文件名,指定了多个文件名时,逐个拷贝
        if [[ ! "${i}" =~ ^-.* ]]; then
            filenames[${#filenames}]=${i}
        fi
    done
    srcdir=$(pwd)
    dirname=${trushbin}/u_${USER}_f_${srcdir##*/}_@_$(date +%Y-%m-%d-%H-%M-%S.%N)
    mkdir ${dirname}
    for i in "${filenames[@]}";
    do
        mv -i "${i}" "${dirname}/"
    done
}

alias rm="put_into_trushbin"

这样
rm -rf abc
就会建立
/opt/.trushbin/u_db_user_f_.trushbin_@_2021-12-16-10-01-36.487838400
目录并将abc移动过去

只实现简单移动,清理和并发问题不考虑,只在bash里使用,zsh能不能用,不知道。

吐槽:
shell编程真难用,用其它高级脚本语言几下能搞定的,shell要费死劲:
数组语法非常丑陋,时间精度不高。

补充内容 (2022-1-10 09:35):
2022/1/10修改了实现方法,从注册函数改为作为命令,避免sudo无法执行

打赏

参与人数 4家元 +80 收起 理由
不长叶子的树 + 10 謝謝分享
没良心的 + 10
abigbell + 20
家睦 + 40

查看全部打赏

发表于 2021-12-16 11:39:24 | 显示全部楼层
还是习惯了用云端git,gitee也能用
项目大,云端放不下的话,本地git可以找一个外部服务器自动同步文件数据,双保险,随时备份
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-12-17 09:09:51 | 显示全部楼层
langren1353 发表于 2021-12-16 11:39
还是习惯了用云端git,gitee也能用
项目大,云端放不下的话,本地git可以找一个外部服务器自动同步文件数据 ...

虽然有内部的git,然而避免不了懒,有本地分枝未推送。

但更重要,连着个smb目录一起给霍霍了..幸好是自己的不然提桶跑路了

写了这个shell后当晚就成功的避免一次手贱rm -rf时没看路径
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2022-1-10 09:35:13 | 显示全部楼层
本帖最后由 aaaadd 于 2022-1-10 15:03 编辑

帖子无法编辑,手动跟楼
经过一段时间愉快的使用,成功又避免了几次手贱,发现1楼的操作有一些不足:
当我以普通用户"越权"删除其它用户建立的文件时,sudo rm -f xxx 命令报错put_into_trushbin命令不存在,
即使使用export -f put_into_trushbin导出也没效果..看来注册成函数有局限,改为作为命令。
在1楼的基础上加了log,用于判断有没运行成功输入文本,赋予777权限,可以愉快的sudo rm -f xxx了
  1. #!/bin/sh
  2. if [ $# == 0 ]; then
  3.     echo *error* no target directory or file
  4.     exit
  5. fi

  6. if [ -z ${trushbin} ]; then
  7.     \rm $@
  8.     echo *warn* delete without trushbin
  9.     exit
  10. fi
  11. filenames=()
  12. for i in "$@";
  13. do
  14.     if [[ ! "${i}" =~ ^-.* ]]; then
  15.         if [ ! -d "${i}" ];then
  16.             if [ ! -f "${i}" ];then
  17.                 continue
  18.             fi
  19.         fi
  20.         filenames[${#filenames[*]}]=${i}
  21.     fi
  22. done
  23. if [ ${#filenames} == 0 ]; then
  24.     echo *error* no target directory or file
  25.     exit
  26. fi
  27. srcdir=$(pwd)
  28. dirname=${trushbin}/u_${USER}_f_${srcdir##*/}_@_$(date +%Y-%m-%d-%H-%M-%S.%N)
  29. mkdir -p ${dirname}
  30. for i in "${filenames[@]}";
  31. do
  32.     echo "mv -i ${i} ${dirname}/"
  33.     mv -i "${i}" "${dirname}/"
  34. done

复制代码

回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-1-10 10:10:15 | 显示全部楼层
aaaadd 发表于 2022-1-10 09:35
帖子无法编辑,手动跟楼

经过一段时间愉快的使用,成功又避免了几次手贱,发现1楼的操作有一些不足:

为啥附件变成-55M了........
回复 支持 反对

使用道具 举报

发表于 2022-1-10 10:21:44 | 显示全部楼层
aaaadd 发表于 2022-1-10 09:35
帖子无法编辑,手动跟楼

经过一段时间愉快的使用,成功又避免了几次手贱,发现1楼的操作有一些不足:

你用插入代码就可以了
  1. export -f put_into_trushbin
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-1-10 15:04:30 | 显示全部楼层
不长叶子的树 发表于 2022-1-10 10:21
你用插入代码就可以了


感谢,莫名其妙出现的序号符号终于没了
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册 微信登录

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-7-21 21:15 , Processed in 0.202801 second(s), 14 queries , Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

快速回复 返回顶部 返回列表