bash&shell系列文章:http://www.cnblogs.com/f-ck-need-u/p/7048359.html


rm的悲剧总是发生在不经意之间,所以无论是在shell脚本中还是交互式bash环境下,执行rm命令时总应该三思三思再三思。也因此,很多人想尽办法防止文件误删除,方法也各种各样。

1.1 alias一般用法

1.默认rm是"rm -i"的别名,ll就是"ls -l"的别名。可以自定义别名来代替某些命令配合某些选项,也可以定义别名组合多个命令。例如:

[root@xuexi ~]# alias ls='ls -lA'

这样在列出目录时将同时列出隐藏文件。

2.使用不带参数的alias将列出当前shell环境下所有的已定义的别名。

3.另外需要说明的是,当别名和命令同名时,将优先执行别名(否则别名就没有意义了),这可以从which的结果中看出:

[root@xuexi ~]# which mv
alias mv='mv -i'
/bin/mv

如果定义的命名名称和原始命令同名(例如定义的别名 ls='ls -l' ),此时如果想要明确使用原始命令,可以删除别名或者使用绝对路径或者使用转义符来还原命令。

4.alias命令是临时定义别名,要定义长久生效的别名就将别名定义语句写入/etc/profile或~/.bash_profile或~/.bashrc,第一个对所有用户有效,后面两个对对应用户有效。修改后记得使用source来重新调取这些配置文件。

5.使用unalias可以临时取消别名。

1.2 alias的缺陷

别名这东西定义和使用起来有点模糊,以下面这个别名命令为例,在有的shell脚本的书籍上使用了这样的定义,但却是错误的,原因稍后说明。

alias rmm='cp $@ ~/backup;rm $@'

该别名的目的是删除文件时先备份到一个目录下,然后再删除。按照man bash里的说明,别名rmm只是第一个cp命令的别名,分号后的rm不是别名的一部分,而是紧跟在别名后的下一行命令。当执行别名rmm时,首先读取别名到分号位置处,然后进行别名扩展,执行完别名命令后,再执行分号后的rm命令。

之所以说上面的命令是错误的命令,问题出在cp的参数"$@",该变量本表示提供的所有参数,但由于cp命令后使用分号分隔并定义了另一个命令,这使得执行别名命令时,参数无法传递到cp命令上,而只能传递到最后一个命令rm上,也就是说cp后的"$@"是空值。所以该别名等价于:

alias rmm='cp ~/backup;rm $@'

是否真的如此,使用echo测试一番即可。

[root@xuexi ~]# alias rmm='echo cp $@ ~/backup;echo rm $@'
[root@xuexi ~]# rmm /etc/fstab /etc/hosts
cp /root/backup
rm /etc/fstab /etc/hosts

从上面的结果中看到cp后的"$@"根本就没有进行扩展,而是空值。

那如果别名定义语句中没有使用分号或其他方法定义额外的命令,而是只有一个命令呢?别名一定就能正确工作吗?非也。以下面的例子为例:

[root@xuexi ~]# alias rmm='echo mv -f $@ ~/backup'

[root@xuexi ~]# rmm /etc/fstab /etc/hosts
mv -f /root/backup /etc/fstab /etc/hosts

发现问题了吗?"$@"是扩展在"~/backup"目录之后的,也就是说下面mv的别名想要替代rm,是无法正常工作的:

alias rm='mv -f $@ ~/backup'

之所以无法正常工作,是因为~/backup也是"$@"的一部分,且是"$@"中最前面的参数。执行下面的命令就知道了:

[root@xuexi ~]# echo mv -f "$@" ~/backup /etc/fstab /etc/hosts
mv -f /root/backup /etc/fstab /etc/hosts

从上面的分析可以知道,alias是有其缺陷的,它只适合进行简单的命令和参数替换、补全,想要实现复杂的命令替代有点难度。因此man bash中建议尽量使用函数来取代别名(For almost every purpose, aliases are superseded by shell functions)。

1.3 别名的最佳实现

毫无疑问,写个shell脚本比别名安全、完整多了,这是替代别名的一种方法。而我个人的建议是,在别名的定义语句中使用函数来克服别名的缺陷。

例如,为了让rm安全执行,使用以下两种方法定义别名:

alias rm='copy1(){ /bin/cp -a $@ ~/backup;rm $@; };copy1 $@'
alias rm='move1(){ /bin/mv -f $@ ~/backup; };move1 $@'

因为执行别名时的参数只能传递给最后一个命令即copy1或move1函数,但"$@"代表的参数可以传递给函数,让函数中的"$@"得到正确的扩展,于是整个别名都能合理且正确地执行。

或者直接定义一个shell function替代rm。例如向/etc/profile.d/rm.sh文件中写入:

function rm(){ [ -d ~/rmbackup ] || mkdir ~/rmbackup;/bin/mv -f $@ ~/rmbackup; }
chmod +x /etc/profile.d/rm.sh
source /etc/profile.d/rm.sh

如此,执行rm命令时,便会执行此处定义的rm函数,使得rm变得更安全。但注意,这样的函数默认无法直接在脚本中使用,除非使用 export -f function_name 导出函数,使其可以被子shell继承。所以,可在/etc/profile.d/rm.sh文件的尾部加上导出语句:

function rm(){ [ -d ~/rmbackup ] || mkdir ~/rmbackup;/bin/mv -f $@ ~/rmbackup; }
export -f rm

如果function名和命令名相同,则默认优先执行function,除非使用command明确指定。例如上面定义了rm函数,如果想执行rm命令,除了使用/bin/rm,还可以如下操作:

command rm a.txt

如果是在shell脚本里涉及到rm命令,那么更建议在每次rm之前先cd到那个目录下,然后再rm相对路径,这样至少能保证不出现符号"/"。当然,更重要的是脚本习惯一些编写脚本的规范,印在骨子里那种,就算想出问题也难。

重新认识alias:通过alias让rm更安全的更多相关文章

  1. 我对alias的重新认识:通过alias让rm更安全

    bash&shell系列文章:http://www.cnblogs.com/f-ck-need-u/p/7048359.html rm的悲剧总是发生在不经意之间,所以无论是在shell脚本中还 ...

  2. linux中的一些基础命令的使用(which,whereis,locate,find,alias,file,ls,cat,echo,tar,bzip2,gzip,history,mv,cp,rm)

    which whereis locate find alias file ls cat echotar bzip2 gzip history mv cp rm -------------------- ...

  3. 快捷键,命令之tab/ history / alias / ls / cd / mkdir / touch /tree /cp /mv /rm /cat /head/grep

    第一阶段 快捷键 1 第二阶段 文件和目录操作命令 1 1.1 date / useradd 1 1.2 echo 调用变量 2 1.3 whoami 查看用户名 2 1.4 tab命令补全 2 1. ...

  4. 命令alias、gerp、find及基础Shell脚本

    一. alias 命令:系统设置命令别名 用法:alias [-p] [name[=value] ... ]    注意‘=’和字符串之间不能包含空格 显示当前设置的别名:alias 或 alias ...

  5. alias别名

    alias一般用法 1.默认rm是"rm -i"的别名,ll就是"ls -l"的别名.可以自定义别名来代替某些命令配合某些选项,也可以定义别名组合多个命令.例如 ...

  6. ~/.bashrc的常用alias设置,30 个方便的 Bash shell 别名

    centos6.5/centos7系统中,alias定义在/etc/bashrc,分别写在/etc/profile.d/*.sh中,可以在此目录添加my.sh,或者~/.bashrc,或者~/.bas ...

  7. bash执行顺序:alias --> function --> builtin --> program

    linux bash的执行顺序如下所示: 先 alias --> function --> builtin --> program 后 验证过程: 1,在bash shell中有内置 ...

  8. Linux Cmd Tool 系列之—alias

    The alias cmd list your current aliases. For example : alias Use alias to shorten a long cmd in curr ...

  9. 友盟推送里面的Alias怎么用?可以理解成账号吗?

    友盟推送里面的Alias怎么用?可以理解成账号吗? 我们的App有自己的账号体系的,想在每次用户登陆的时候,给用户发一个欢迎消息. 看了一下友盟推送,里面有一个概念叫做Alias(别名),但是官方文档 ...

随机推荐

  1. 【TCP/IP详解 卷1:协议】 第18章TCP连接的建立与终止

    img { border: 1px solid black } T C P是一个面向连接的协议.无论哪一方向另一方发送数据之前,都必须先在双方之间建立一条连接. RST:复位连接,将连接重置,一般用在 ...

  2. Egret index.html设置

    <!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title> ...

  3. Hibernate使用注解进行ORM映射实例

    在上一篇博客中,我们通过xml配置文件进行实体类和表的映射,但是近两年来有更多的项目对一些比较稳定的实体类使用了注解进行ORM映射,这样使得编程更加简洁.简单.其实使用注解进行ORM映射和使用xml进 ...

  4. office 2013幻灯片中插入SmartArt图形时出现错误下列一个或多个文件由于包含错误而无法运行

    office 2013幻灯片中插入SmartArt图形时出现错误下列一个或多个文件由于包含错误而无法运行 系统:win8 64位 PowerPoint2013 64位 在幻灯片中插入SmartArt图 ...

  5. mysql基础之yum安装mysql5.7.18

    2017-04-19 一.实验环境 centos7_x64 由于centos7的yum源里默认使用了mariadb替代了mysql,所有我们还得先配置一下yum源.当然mariadb和mysql是兼容 ...

  6. Hibernate框架 主配置文件(Hibernate.cfg.xml) 映射配置 说明

    Hibernate.cfg.xml 主配置文件中主要配置:数据库连接信息.其他参数.映射信息! 常用配置查看源码: hibernate-distribution-3.6.0.Final\project ...

  7. CSS3-loading动画(三)

    分享继续,图片看得不真切 在线演示demo:http://liyunpei.xyz/loading.html 十一.效果十一 四个小球分别包含于四个正方形div,将小球相对于正方形定位(top:0:l ...

  8. 游戏里的动态阴影-ShadowMap实现原理

    ShadowMap是比较流行的实时阴影实现方案,原理比较简单,但真正实现起来还是会遇到很多问题的,我这里主要记录下实现方式 先看效果 凹凸地形上也有阴影 实现原理 ShadowMap技术是从灯光空间用 ...

  9. Linux日志分析ELK环境搭建

    场景:ELK作为一个日志收集和检索系统,感觉功能还是相当的强大的. ELK是啥, 其实是是三个组件的缩写, 分别是elasticsearch, logstash, kibana. ELK平台可以用于实 ...

  10. jsp元素

    1.指令元素:用于在JSP转换为Servlet阶段提供JSP页面的相关信息,如页面采用的字符编码集.页面中需要导入的类等信息,指令元素不会产生任何的输出到当前JSP的输出流中 指令元素有三种指令:pa ...