我在 DigitialOcean 等“自我管理 shell”托管提供商上使用 Ubuntu 和 Bash 构建了一些服务器环境,我在其中运行了 Drupal/WordPress 应用程序。
一直以来我都没有必要使用所谓的“命令替换”。
我问,Bash 程序员必须使用这个概念的“模式”会出现什么问题?请举个例子?
答案1
命令替换意味着运行 shell 命令并将其输出存储到变量或使用 echo 命令显示回来。例如,显示日期和时间:
echo "Today is $(date)"
当我的命令接收另一个命令或示例的输出作为参数时,它很有用。
答案2
命令替换允许用命令的输出来替换命令名称本身。
命令替换允许以一种方便的方式使用命令的输出,而无需先将其写入临时文件,然后从该文件中读取。如果命令的输出是单行上的短字符串,则最好这样做。
有些人使用命令替换来收集命令的输出,即使输出量可能是多行文档。这一般是不是使用命令替换的好方法。相反,应该使用标准 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 脚本中编写的或在命令行上键入的一样。