有没有一种简单的方法来列出由于涉及别名命令的bashrc更新而导致系统中发生的所有命令冲突?
例如,有人alias ls=/path/to/user-generated/executable用bashrc 编写。如何发现这掩盖了实际命令(ls)。一种方法似乎是在采购bashrc之前和之后运行所有别名并比较输出。有没有更好的方法?
我正在运行Ubuntu 12.04。
bash --version
GNU bash版本4.2.24(1)-发行版(i686-pc-linux-gnu)
有没有一种简单的方法来列出由于涉及别名命令的bashrc更新而导致系统中发生的所有命令冲突?
例如,有人alias ls=/path/to/user-generated/executable用bashrc 编写。如何发现这掩盖了实际命令(ls)。一种方法似乎是在采购bashrc之前和之后运行所有别名并比较输出。有没有更好的方法?
我正在运行Ubuntu 12.04。
bash --version
GNU bash版本4.2.24(1)-发行版(i686-pc-linux-gnu)
Answers:
您可以使用它type来查找bash如何解释命令。
type ls打印ls is aliased to `ls --color=auto'。
which,但是如果两个(类型,哪个)shell内建函数相同,我现在就不这样做。
type which告诉您which is /usr/bin/which,所以它不是内置函数。因此,它不能告诉您某些东西是否是内置的(例如which echovs type echo)。
type which which is a shell builtin我正在使用zsh。
作为第一个问题,无法列出冲突,因为bash在内部使用哈希表,因此它仅记录最后一个替代。
要确定命令是否为别名,请alias ls在您的情况下使用,如果命令告诉您“未找到”之类的信息,则它不是别名,否则为别名。
要启动不考虑别名的原始功能,请在斜杠前面加上一个斜杠(例如,\ls将启动真实的哈希ls),请忽略别名。
编辑
如果您想快速知道命令是否为别名,则可以通过set -x执行ls以下命令启用调试模式:

您将看到正在执行的真实命令的调试输出
要取消设置调试模式,请使用 set -
alias一部分。如果用户不知道存在命令(例如ls)怎么办?运行后,他似乎只知道alias ls映射的内容,而不是原始映射的内容。我猜一个人将不得不使用和不使用\来运行所有命令来查找冲突。
您可以使用内置的bash compgen来获取所有命令和所有别名的列表compgen -ac。任何也是别名的命令都将在此列表中重复,因此简单的天真解决方案是在中输出查找重复项compgen -ac。
但是,如果命令在路径上两次出现,则可能还会出现重复项。举例来说,我有/bin/which和/usr/bin/which这样compgen -ac会列出which两次,即使它不是一个别名。
因此,需要从中获取所有重复项compgen -ac并将其与别名列表进行比较。只有也是别名的重复项才是那些隐藏命令的别名。我们可以使用comm(1)命令和bash进程替换来做到这一点。
comm -12 <(compgen -a | sort) <(compgen -ac | sort | uniq -d)
compgen -a | sort是所有别名的列表(按排序comm)。compgen -ac | sort | uniq -d是命令和别名列表中所有重复项的列表。comm -12仅输出两个共同的行。
您可以使用shell调试功能来确切了解bash调用交互式shell时发生的情况。下面应该显示从登录shell生成交互式shell时分配的所有别名:
bash -x -l -i -c 'exit' 2>&1 | grep ' alias '
-x ->启用调试-l ->登录外壳-i ->交互式外壳-c ->命令需要运行命令出口,以便外壳程序返回。该-i在这种情况下,因为需要的bash不会建立一个互动的环境,否则运行命令。
这是我系统中的一个示例:
$ bash -x -l -i -c 'exit' 2>&1 | grep ' alias '
++ alias 'ls=ls --color=auto'
$ alias -p
alias ls='ls --color=auto'
为了查看在分配别名以确定文件出现时最后一个来源的文件,可以扩展grep:
bash -x -l -i -c 'exit' 2>&1 | grep -E ' (alias|[.]|source) '
这可能会返回误报,但如果您正在手动检查返回的数据,那应该没问题。执行命令前面的“ +”号表示深度。
+ . /home/jordan/.bashrc
++ alias 'ls=ls --color=auto'
++ . /home/jordan/.foo
+++ alias t=test
++ alias t=test2
在此示例输出中,它显示了.bashrc为ls.foo别名设置了别名t,然后.bashrc覆盖了t。的先前别名。