有没有一种简单的方法来列出由于涉及别名命令的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 echo
vs 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
。的先前别名。