下划线变量有什么实际用途吗?

下划线变量有什么实际用途吗?

当我们运行命令时,最后一个参数将被保存在_其中,我们可以访问:

$ echo $_

听起来不像是一个非常有用的功能。那为什么还要麻烦呢?有没有实际应用?

答案1

它具有交互用途,并且可以被用来进行“代码高尔夫”。

它可以通过避免需要临时变量来减少代码,例如:

temp=$destdir/$outfile
cp $infile $temp
chmod go-w $temp

cp $infile $destdir/$outfile
chmod go-w $_

$_我在其中没有看到这个功能特殊参数POSIX 的;它是 Bash 扩展(可能在其他 shell 中)。

这是一个实施得很糟糕的黑客,当你设置陷阱时就会中断debug,如以下脚本所示:

#!/bin/bash

dbg()
{
  :
}

echo abc
echo $_

trap dbg debug

echo abc
echo $_

Bash 4.4.20 下的输出是:

$ ./underscore.sh
abc
abc
abc
dbg

您可以看到,当我们启用调试陷阱后,$_不再呈现预期值。在规范中,“最后一个命令”字面意思是指最近执行的命令,而不是命令序列中的上一个命令。abcecho abc$_

您绝对不想在任何人可能想要使用在调试陷阱的帮助下实现的调试器进行调试的任何 Bash 程序中使用它。

的交互式使用$_是相同的:参考上一个命令的最后一个参数。这就提出了一个问题:为什么有人会使用这个而不是命令之一M-_或者M-.将相同的项目扩展到命令行中?

其差异在于$_

  • 它比长路径的扩展要紧凑得多。

  • 当从历史记录中调用命令时$_,它不再指历史记录中的前任命令,而是指最近执行的命令。这可以被利用。我们可以回忆并重新使用包含$_对最近使用的右侧参数进行操作的命令,而不是使用相同的参数完全重复旧命令。

  • 生成的内容M.基于原始的、未扩展的命令行,而$_生成上一个命令的实际最后一个参数。我们可以这样展示这种差异:

    $ echo a{b,c}
    ab ac
    $ echo $_
    ac
    $ echo a{b,c}
    $ echo █
    

    在光标块指示的点处,键入M.命令。 MetaM可以是EscAlt修饰符。结果是:

    $ echo a{b,c}█
    

    换句话说,a{b,c}插入来自上一个命令的原始非空白最后一个标记,而不是语义 item ac。这看起来更像是 GNU Readline 功能,而不是 GNU Bash 功能。

答案2

我经常在组合中使用它

mkdir verylongdirectoryname
cd $_

相关内容