命令替换
Contents
1. 概述
当我们有复杂的 shell 脚本时,我们经常需要在我们的逻辑中使用其他命令的输出。 在这个快速教程中,我们将看到如何使用命令替换来做到这一点。
2. 语法
我们先来看看语法。由于历史原因,我们可以使用两种语法:
$(command)
`command`
**推荐使用第一种形式,**因为它解决了不一致的行为。它也更具可读性。
我们应该记住,命令替换会产生一个sub-shell 。
让我们看一个简单的例子:
$ echo "Current path is ["$(pwd)"]"
Current path is [/home/blogdemo]
这也适用于旧语法:
$ echo "Current path is ["`pwd`"]"
Current path is [/home/blogdemo]
*在此示例中,*pwd 命令的输出替换了实际的 command。
那么格式之间有什么区别呢?
让我们考虑这个例子:
$ function different_syntax() {
echo "Backticks ["`echo \\blogdemo`"]"
echo "Dollar ["$(echo \\blogdemo)"]"
}
$ different_syntax
Backticks [blogdemo]
Dollar [\blogdemo]
反斜杠以不同的方式处理反斜杠字符。具体来说,当它后面跟着*$、 ` (反引号)或\*时,它的行为会有所不同。
考虑我们有一个变量指向一个存在的目录:
$ function different_syntax() {
dir="/home"
echo "Backticks ["`ls \$dir`"]"
echo "Dollar ["$(ls \$dir)"]"
}
$ different_syntax
Backticks [blogdemo demo]
ls: cannot access '$dir': No such file or directory
Dollar []
在第一种情况下,反斜杠不会转义*$*字符,并且变量会扩展为它的值。
3. 引用和嵌套
现在我们已经了解了基本语法,让我们看看一些高级场景。
我们可以在命令替换表达式中使用嵌套:
$ function nesting() {
current_folders=$(ls $(pwd))
echo "Current folders in $(pwd) ["$current_folders"]"
}
$ nesting
Current folders in /home [blogdemo demo]
首先,当前路径替换pwd命令。然后,我们将它传递给ls 并用它的输出替换整个表达式。最后,我们将输出存储在一个变量中。
$ function quoting() {
for element in $(ls $(pwd))
do
echo "["$element"]"
done
}
$ quoting
[blogdemo]
[demo]
在这种情况下,我们遍历当前目录中的所有文件。
现在让我们看看如果我们在循环中使用引号会发生什么:
$ function quoting() {
for element in "$(ls $(pwd))"
do
echo "["$element"]"
done
}
$ quoting
[blogdemo demo]
由于没有发生分词,我们迭代单个元素。 让我们以一个有用的片段结束:
$ ps -g $(ps -C firefox -o sid=)
PID TTY TIME CMD
1652 ? 00:02:48 gnome-shell
1815 ? 00:00:12 Xwayland
2207 ? 00:00:09 ibus-daemon
2214 ? 00:00:00 ibus-dconf
2215 ? 00:00:02 ibus-extension-
2217 ? 00:00:00 ibus-x11
2232 ? 00:00:02 ibus-engine-sim
2533 ? 00:09:36 firefox
2670 ? 00:00:32 WebExtensions
...
让我们看看它的作用。首先,我们使用ps 命令搜索特定进程并打印其会话 ID。 我们在输出说明符之后使用*=*来抑制嵌套命令中的标题。
然后我们使用这个输出(会话 ID)来打印这个特定会话中的所有进程。