在 bashrc 中使用别名时如何测试可能的冲​​突?

use*_*107 12 bash alias bashrc

是否有一种简单的方法可以列出由于涉及别名命令的 bashrc 更新而导致系统中发生的所有命令冲突?

比如有人alias ls=/path/to/user-generated/executable用bashrc写的。人们如何发现这掩盖了实际命令 ( ls)。一种方法似乎是在采购 bashrc 之前和之后运行所有别名并比较输出。有没有更好的方法?

我正在运行 Ubuntu 12.04。

bash --version

GNU bash,版本 4.2.24(1)-release (i686-pc-linux-gnu)

cho*_*oba 15

您可以使用type来了解 bash 如何解释命令。


Tho*_*hor 8

要找出别名掩盖了哪些命令,请执行以下操作:

alias | sed 's/^[^ ]* *\|=.*$//g' | while read a; do
  printf "%20.20s : %s\n" $a "$(type -ta $a | tr '\n' ' ')"
done | awk -F: '$2 ~ /file/'
Run Code Online (Sandbox Code Playgroud)

解释

alias单独列出定义的别名并sed提取它们的名称。while 循环type -ta在它们中的每一个上运行并awk打印包含别名和文件的行。


dai*_*isy 7

作为您的第一个问题,无法列出冲突,因为 bash 在内部使用哈希表,它只记录最后一次覆盖。

要确定命令是否是别名,请alias ls在您的情况下使用,如果它告诉您诸如“未找到”之类的信息,则它不是别名,否则就是。

要启动原始函数而不考虑别名,请添加斜杠前缀,例如\ls将启动真正的散列 ls,忽略别名。

编辑

如果你想快速知道一个命令是否是别名,你可以通过 启用调试模式set -x,现在如果你执行ls

在此处输入图片说明

您将看到正在执行的真实命令的调试输出

要取消设置调试模式,请使用 set -


cam*_*amh 6

您可以使用 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) 
Run Code Online (Sandbox Code Playgroud)

compgen -a | sort是所有别名的列表(按 排序comm)。compgen -ac | sort | uniq -d是命令和别名列表中所有重复项的列表。comm -12只输出两者共有的那些行。


jor*_*anm 5

您可以使用 shell 调试功能准确查看 bash 调用交互式 shell 时发生的情况。以下应显示从登录 shell 生成交互式 shell 时分配的所有别名:

bash -x -l -i -c 'exit' 2>&1 | grep ' alias '
Run Code Online (Sandbox Code Playgroud)
  • -x -> 启用调试
  • -l -> 登录外壳
  • -i -> 交互式外壳
  • -c -> 命令

需要运行命令 exit 以便 shell 返回。该-i在这种情况下,因为需要的bash不会建立一个互动的环境,否则运行命令。

这是我系统中的一个示例:

$ bash -x -l -i -c 'exit' 2>&1 | grep ' alias '
++ alias 'ls=ls --color=auto'
$ alias -p
alias ls='ls --color=auto'
Run Code Online (Sandbox Code Playgroud)

为了查看在分配别名以确定它发生的文件时上次获取的文件,您可以扩展 grep:

bash -x -l -i -c 'exit' 2>&1 | grep -E ' (alias|[.]|source) '
Run Code Online (Sandbox Code Playgroud)

这可能会返回误报,但如果您手动检查返回的数据应该没问题。执行命令前面的“+”符号的数量表示深度。

+ . /home/jordan/.bashrc
++ alias 'ls=ls --color=auto'
++ . /home/jordan/.foo
+++ alias t=test
++ alias t=test2
Run Code Online (Sandbox Code Playgroud)

在这个示例输出中,它显示 .bashrc 为ls、 .foo aliases设置了一个别名t,然后 .bashrc 覆盖了之前的别名t