利用 alias 自定义一个删除备份命令

这篇文章来记录下如何在 linux 中使用 alias 自定义一条删除备份命令。

1. 需求背景

平时我们基本上都使用 rm 命令来删除不需要的文件,但是这个命令还是挺危险的,如果因为不小心删除了一些非常重要的文件,那基本上是恢复不会来了,因为我自己前些天就因为按 tab 的时候没注意补全的信息,直接就回车了……删除了一个很重要的代码源文件。

后面开始查找如何在 linux 下面回复删除的文件。尝试了网上介绍的一些方法,发现仍然不行,遂放弃……

于是就想:linux 中能不能像 windows 下面一样,如果不是强制删除文件,那么这些被删除的文件首先是存放在 回收站 的,除非人为清空回收站,否则这些被“删除”的文件没有被真正删除。

于是开始搜寻资料,最后发现可以使用 alias 来实现这个需求。

2. 具体实现

2.1 .bashrc 相关背景

先简单介绍下 .bashrc 文件的相关背景。

.bashrc 存放在 home 目录下面。. 开头的文件表示为了防止文件被意外修改,而默认不显示。使用 ls 命令是不显示这个文件的,只有使用 ll 才看得到。

.bashrc 相当于配置文件,bash shell 每次启动时都会首先读取 .bashrc 文件,完成配置更新。

2.2 alias 相关背景

这里先解释下,alias 的功能是提供命令简写,举个例子,在 .bashrc 文件中有下面几行代码:

1
2
3
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'

这里的 ll 就是命令 ls -alF 的一个别名,起到的效果是一样的。(注意等号 = 两边不能有空格)

如果要查看系统中共有多少条简写命令,可以使用:

1
alias -p

结果如下,这是我系统中目前所有的 alias

1
2
3
4
5
6
7
8
9
ubuntu@VM-0-14-ubuntu:~$ alias -p
alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l='ls -CF'
alias la='ls -A'
alias ll='ls -alF'
alias ls='ls --color=auto'

2.3 将所有的自定义命令放在 .bash_aliases 文件里

这里需要解释下为什么文件名为 .bash_aliases。用 vim 打开 .bashrc ,里面有一段这样的代码:

1
2
3
if [ -f ~/.bash_aliases ]; then  # 表示如果在 home 目录下面存在 .bash_aliases 文件
. ~/.bash_aliases # 那么执行这个文件。. 表示执行
fi

一个比较推荐的方法是:将所有的自定义命令统一存放在 .bash_aliases 里。当然,如果直接把 alias 语句放在 .bashrc 里也能实现相应功能,只不过这种做法不推荐。

默认情况下,home 目录下是没有 .bash_aliases 文件的,我们需要自己用 touch 新建一个。

我们首先添加一个 ws 命令,方便我们在任何目录下,只需要输入 ws 就能回到 workspace 目录:

1
alias ws='cd ~/workspace'

保存退出后 ws 命令还不能马上生效,我们还需要执行(先切换到 home 目录下):

1
source .bashrc

现在我们就能在任意目录下使用 ws 这个命令了。

有了上面的实践之后,我们已经知道 alias 的原理了。接下来我们新建一个 del 命令,是一个 “假删除” 的命令:即并不真正删除文件,而是将文件移动到一个特定位置。

vim 打开 .bash_aliases 文件,在文件尾部添加如下代码(所有的等号两边不能有空格):

1
2
3
4
5
6
7
8
9
function delete_and_back_file() {
date=`date +%Y%m%d`
path=`pwd $1`
output_path=~/backup/$date
mkdir -p ${output_path}/
mv $path/$1 ${output_path}/$1
}

alias del='delete_and_back_file'

下面解释下上面的代码。

因为我们想要实现的 del 命令其实是一个 移动文件 的命令,这就涉及到 源目录目标目录,我们的

1
del ./xxx.txt

等价于:

1
mv ./xxx.txt <目标目录>

上述命令中,我们需要给定一个参数,即 xxx.txt ,表示想要删除的文件名。因为每次需要删除的文件都不同,等价于一个变量,我们不好直接使用 alias 来简写,这时候就需要使用函数。

  • 代码第四行:output_path 表示我们想要把文件移动到哪个 目标目录 下,可以自定义;
  • 代码第五行:mkdir -p 表示递归新建目录。举个例子,加入我们需要在 home 目录基础上新建 ~/dir1/dir2 目录:
    • 如果直接使用 mkdir ~/dir1/dir2 是执行不了的;
    • 这时候就需要使用 -p 参数,表示递归建立目录;
    • 即首先新建 dir1 目录,然后在 dir1 下面再新建 dir2 目录。
  • 代码第九行:将这个函数名赋值给我们的自定义命令 del (如果我们将自定义命令命名为 rm,那么会覆盖掉系统中的 rm 命令,这时候如果需要调用系统命令,需要使用 \ 进行转义,即输入 \rm )。

最后,我们在执行:

1
source .bashrc

至此,我们就可以在任意目录下面调用 del 命令了。它不会真正的删除文件,只是将文件移动 .bash_aliases 中指定的目录下。

3. Drawbacks

目前的主要缺陷是 del 后只能跟一个文件名,无法一次性删除多个文件,无法使用 -r 删除一个文件夹。

不过这些实现起来应该不难,只需要修改 del_and_back_file 函数即可。等 shell 更加熟练后,可以来实现这个需求。

4. References

Donate comment here