什么问题/模式证明使用命令替换是合理的?

什么问题/模式证明使用命令替换是合理的?

我在 DigitialOcean 等“自我管理 shell”托管提供商上使用 Ubuntu 和 Bash 构建了一些服务器环境,我在其中运行了 Drupal/WordPress 应用程序。

一直以来我都没有必要使用所谓的“命令替换”。

我问,Bash 程序员必须使用这个概念的“模式”会出现什么问题?请举个例子?

答案1

命令替换意味着运行 shell 命令并将其输出存储到变量或使用 echo 命令显示回来。例如,显示日期和时间:

echo "Today is $(date)"

当我的命令接收另一个命令或示例的输出作为参数时,它很有用。

答案2

POSIX 标准中的命令替换小节:

命令替换允许用命令的输出来替换命令名称本身。

命令替换允许以一种方便的方式使用命令的输出,而无需先将其写入临时文件,然后从该文件中读取。如果命令的输出是单行上的短字符串,则最好这样做。

有些人使用命令替换来收集命令的输出,即使输出量可能是多行文档。这一般是不是使用命令替换的好方法。相反,应该使用标准 Unix 习惯用法,即使用管道或临时文件在处理阶段之间传递数据。


我使用的命令替换示例:

例如,要确定当前用户是否以 root 身份执行脚本:

if [ "$( id -u )" -ne 0 ]; then
   echo 'This script requires root privileges, re-run with sudo' >&2
   exit 1
fi

命令$(id -u)替换将替换为 的输出id -u,这将返回当前用户的 UID(整数)。

另一个例子。我正在使用 GnuPG 来签署git提交。为了使 GnuPG 正常工作,我需要GPG_TTY在交互式 shell 的初始化文件中设置当前终端设备的名称。我这样做与

export GPG_TTY="$( tty )"

这取决于当前终端设备在 shell 会话中的位置GPG_TTY/dev/ttyp4

另一个例子。我有一个脚本,必须将在 Solaris 计算机上运行视为特殊情况:

case "$( uname -s )" in
    SunOS)
        # code specific for Solaris
        ;;
    *)
        # code for all other Unix platforms
esac

另一个例子。该getconf PATH命令返回当前系统的“默认路径”。我在某些情况下使用它来将PATH变量重置为“正常的默认”值:

PATH="$( getconf PATH )"

答案3

我经常使用它find,例如:

tar cvf ../junk.tar `find .`

另外,作为穷人 IDE 的一部分:

vi `grep mysearcstring *.[ch]`

以上是命令行示例。我也在脚本中经常使用它,如果没有它,我会感到很困难。最常见的情况可能是如上所述,从命令的输出设置 shell 变量:

NOW=`date`

我按照旧习惯使用反引号,但$(command)语法要好得多,因为您可以将一个反引号嵌入到另一个反引号中。使用反引号,您必须知道在哪里放置转义\字符,这很麻烦。

答案4

使这种用法成为必要的实现模式是 Unix shell 在子进程中执行每个非内置命令。子进程不能修改其父进程的上下文。命令替换可能会导致 shell 使用非内置命令的文本输出,就好像它是在 shell 脚本中编写的或在命令行上键入的一样。

相关内容