如何通过别名或函数查看 shell 中实际运行的命令

如何通过别名或函数查看 shell 中实际运行的命令

例如,我有一个 bash 函数(或别名)function install() {sudo apt-get install $@}。运行命令时install dicelab,我期望实际运行的是sudo apt-get install dicelab.我在哪里可以看到 shell 实际运行的内容?我想确保我的更复杂的别名能够按预期工作。

答案1

set -x在外壳中使用。

$ alias hello='echo hello world!'
$ hello
hello world!
$ set -x
$ hello
+ echo hello world!
hello world!

使用set -x打开xtraceshell 选项(set +x将其关闭)并且应该适用于所有类似 Bourne 的 shell,例如bashdash ksh93和。这会提示 shell 显示在执行别名扩展和变量扩展等后执行的命令。pdkshzsh

输出将位于 shell 的标准错误流上(就像普通提示符一样),因此它不会干扰标准输出的重定向,并且前面会出现由PS4shell 变量定义的提示符(通常+␣是默认情况下)。

具有一些功能的示例:

$ world () { echo "world"; }
$ hello () { echo "hello"; }
$ helloworld () { printf '%s %s!\n' "$(hello)" "$(world)"; }
$ helloworld
hello world!
$ set -x
$ helloworld
+ helloworld
++ hello
++ echo hello
++ world
++ echo world
+ printf '%s %s!\n' hello world
hello world!

根据您的具体示例(语法已更正并添加了引号):

$ install () { sudo apt-get install "$@"; }
$ set -x
$ install dicelab
+ install dicelab
+ sudo apt-get install dicelab
bash: sudo: command not found

(我的系统上没有使用或安装过sudo,因此该错误是预料之中的。)

请注意,已经调用了一个通用实用程序,因此如果您在某些时候想要使用该实用程序,则可能需要为install您的函数命名其他名称( ?)。aptin


请注意,跟踪输出是调试输出。它是一个表示执行命令时 shell 正在做什么。您在屏幕上看到的输出可能不适合 shell 输入。

另请注意,我bash在上面使用了。其他 shell 可能有另一个默认跟踪提示(例如zsh,包含字符串和当前命令的历史记录编号),或者可能不会像嵌套调用zsh那样“堆叠”提示。bash


默认情况下,我正在运行我以前set -x在所有交互式 shell 中运行的命令。很高兴看到实际执行的内容......但我注意到可编程选项卡完成等可能会在某些 shell 中导致不需要的跟踪输出,并且某些 shell 在其默认跟踪输出中有点冗长(例如zsh)。

答案2

您可以使用,默认情况下shell-expand-line它绑定到 Control- Alt- :e

$ bind -p | grep shell-expand-line
"\e\C-e": shell-expand-line

除此之外,它会将当前行中的别名替换为其定义,以便您可以看到您仍在使用的命令即将跑步。例子:

$ install dicelab # now press C-Alt-e
$ sudo apt-get install  dicelab # the above line will be replaced with this

答案3

使用内置命令type查看您要运行的别名或函数定义

此解决方案不需要运行命令

$ type ls
ls is aliased to `ls --color=auto -p'
$ type -a ls
ls is aliased to `ls --color=auto -p'
ls is /bin/ls

From help type-a显示包含名为 NAME 的可执行文件的所有位置;包括别名、内置函数和函数,当且仅当未使用“-p”选项时

$ function hello() { echo hello; }  # define function
$ type hello
hello is a function
hello () 
{ 
    echo hello
}

答案4

对于特定别名的一个简单方法是尝试

如果你这样做ps-f,您将看到进程旁边的实际命令,不是姓名。您可以通过定义以下别名来验证这一点:

alias doSleep="sleep 100"

然后做

ps -f | grep "sleep"

你会看到

username   14303    2409  0 15:16 pts/0    00:00:00 sleep 100

不幸的是,命令仅显示别名,因此您无法使用历史记录来验证实际命令是否运行;在这种情况下,您只能搜索别名标签。

相关内容