bash - 如何在使用的同时增强内置的 shell 功能
问题描述
大多数时候 id 不仅喜欢查看特定命令的位置,还喜欢查看它是什么。一个例子which lsd
告诉我这个命令是有效的并且存在于 中/usr/local/bin/lsd
,但更有趣的信息是:它的一个链接../Cellar/lsd/0.16.0/bin/lsd
告诉我它是一个由 homebrew 管理的命令。
所以要同时查看两者,我想创建一个别名。但是别名似乎不能很好地处理参数,甚至对于可能有效的简单命令,我没有让它与内联命令执行一起工作,例如$(which $1)
。接下来我创建了一个shell函数来正确使用命令参数:
function dings() {
command=`which $1`
echo $command
eval "$command --version" # might not be supported by all commands
ll $command
}
这个功能有点像我想要的那样:
除了一件事:我必须记住函数名并使用它而不是which
. 所以我尝试为该函数起别名,但他正在产生奇怪的东西,因为这会导致递归调用自身 - 这很糟糕。由于这不是命令,我也不能使用它的确切位置来省略这个“错误”。
所以问题是:如何which
用我自己的仍然使用默认值的函数替换内部 shell 函数which
?
另外:我如何能够显示所有找到的相关命令实例?因此,就我而言,lsd
我的系统中有两个版本。路径中的第一个是较旧的 brew 版本,路径中的第二个是cargo
版本。
解决方案:
function which() {
IFS='
'
set -f
for LINE in `type -a $1`; do
COMMAND=`echo $LINE | cut -d ' ' -f 3`
if [[ $COMMAND = /* ]]; then
version=`$COMMAND --version 2>/dev/null` # might not work with all commands
[[ -n "$version" ]] && version="($version)"
echo "$1 is $COMMAND $version"
ll $COMMAND
else
echo $LINE
fi
done
}
解决方案
您的问题“我如何选择使用哪个”的直接解决方案是用于抑制 shell 函数查找which
的内置函数:command
which() {
command which "$1"
"$1" --version
ll "$(command which "$1")"
}
这也避免了不必要的eval
并且不使用临时变量。如果要避免运行which
两次,可以使用临时变量,但不要将其泄漏到环境中:
which() {
local whichpath
whichpath=$(command which "$1")
printf '%s\n' "$whichpath"
"$1" --version
ll "$whichpath"
}
但是您可以完全避免使用外部命令which
,而是使用内置命令type
:
type() {
local typepath
typepath=$(command type -p "$1")
printf '%s\n' "$typepath"
"$1" --version
ll "$typepath"
}
请注意,如果您使用它来查找不是可执行文件的内容,这将中断。
或者,如果你真的想迷惑未来的自己,你可以调用函数which
,但type
在后台使用:
which() {
local typepath
typepath=$(type -p "$1")
printf '%s\n' "$typepath"
"$1" --version
ll "$typepath"
}
旁注:这使用ll
别名,通常在非交互式 shell 中禁用(例如在运行脚本时);不过,它很可能在ll
定义的交互式会话中运行。只要知道,如果你要在脚本中使用它,你最好使用它ls -l
而不是ll
别名。
推荐阅读
- pickle - 如何腌制/序列化 swigpyobject?
- mysql - mysql安装程序没有配置mysql
- angular - 每次更改检测在组件级别运行时,有没有办法记录?
- php - 将活动 CSS 类添加到菜单项
- python - 如何打印文本每个句子中的前两个单词
- python - 不断收到 IDLE 内部异常 TypeError,但它没有告诉我问题出在哪里
- java - TextView的背景没有改变
- ios - Ionic 5 - ion-item 需要在 IOS 中点击 2 次才能触发 onclick 事件
- sql - sql连接两个带有avg的表
- firebase - Firebase Messaging 无法发送后台消息 Flutter