我使用 Bash 作为交互式 shell,我想知道是否有一种简单的方法可以让 Bash 运行系统命令而不是 shell 内置命令(在它们共享相同名称的情况下)。
例如,使用系统kill
(from util-linux
) 打印指定进程的进程 id (pid),而不是发送信号:
$ /bin/kill -p httpd
2617
...
如果不指定系统命令的完整路径,则使用 Bash 内置命令代替系统命令。内置kill
命令没有该-p
选项,因此命令失败:
$ kill -p httpd
bash: kill: p: invalid signal specification
我尝试了中列出的答案让 bash 使用外部 `time` 命令而不是 shell 内置命令但它们中的大多数只能工作,因为time
实际上是一个外壳关键词– 不是贝壳内置。
除了暂时禁用内置的 Bash 之外enable -n kill
,到目前为止我见过的最好的解决方案是使用:
$(which kill) -p httpd
是否有其他更简单(涉及更少的输入)的方法来执行外部命令而不是 shell 内置命令?
请注意,这kill
只是一个例子,我想要一个广义的command
解决方案类似于使用内置前缀阻止运行与外部命令同名的函数的方式。在大多数情况下,我通常更喜欢使用内置版本,因为它可以节省分叉新进程,有时内置版本具有外部命令没有的功能。
答案1
假设env
在你的路径中:
env kill -p http
env
在(可能)修改过的环境中运行由第一个参数命名的可执行文件;因此,它不知道也不使用 shell 内置命令。
这会产生一些 shell 作业控制问题,但不依赖于外部命令:
exec kill -p bash &
exec
需要一个可执行文件来替换当前的 shell,因此不使用任何内置命令。该作业在后台运行,以便您替换分叉的后台 shell,而不是当前的 shell。
答案2
做你想做的事情的最简单的方法可能是把这条线
alias kill="/bin/kill"
到你的~/.bashrc
文件中。之后,每次新登录/调用 bash 都会将“kill”解释为/bin/kill
。
答案3
如果您知道一个需要一些打字的解决方案,并且您想要一个需要较少打字的解决方案,请构建它:
runFile() { local cmd="$1"; shift; cmd="$(which "$cmd")" && "$cmd" "$@"; }
计算机擅长缩写通常需要花费一些精力的内容。
答案4
(在 zsh 中)您可以在任何命令名称前加上 = 符号以获取系统版本,而不是内置版本。这也是一种避免在特定场景中造成混乱的别名的便捷方法。
$ =kill -p httpd