bash - 通过 Bash 中的连接将扩展变量作为另一个命令的参数
问题描述
想象一下,我想some-command
通过$()
存储在另一个变量中的参数调用某个命令argument
,后者包含空格。
result="$(some-command $argument)"
以我目前的理解, (例如扩展)导致传递两个参数的事实正如预期的那样。问题部分:为什么
result="$(some-command "$argument")"
(例如连接)会导致传递一个参数的预期结果?
更多细节:
./some-command
:
#!/usr/bin/env bash
echo "Arg 1: $1"
echo "Arg 2: $2"
./test-script
:
#!/usr/bin/env bash
export PATH="`pwd -P`:$PATH"
argument="one two"
echo "Calling with expansion"
res="$(some-command $argument)"
echo $res
echo "Calling with concatenation"
res="$(some-command "$argument")"
echo $res
调用test-script
导致以下输出:
Calling with expansion
Arg 1: one Arg 2: two
Calling with concatenation
Arg 1: one two Arg 2:
我似乎不明白何时扩展/评估 smth 以及如何将扩展变量分组为传递给脚本的参数。
谢谢!
PS 额外的好奇心是为什么result="$(some-command \"$argument\")"
根本不起作用。
解决方案
这就是 bash 中引用和扩展的工作方式。其实后面的双引号=
是不需要的,因为不进行分词,所以
result=$(some-command "$argument")
应该以同样的方式工作。
没有“串联”发生。Bash 将内部的字符串$()
视为命令,并在运行之前对其进行所有扩展。
那么,会发生什么some-command "$argument"
?首先,参数扩展将 $argument 扩展为包含空格的字符串。当发生分词时,它会指出字符串用双引号引起来,因此它将其保留为单个字符串。
推荐阅读
- python - Django - 使用用户输入的 id 更新模型
- android - TextWatcher 仅监视当前输入
- amazon-web-services - 一个 AWS 账户中的 Elastic Beanstalk 能否与另一个 AWS 账户中的 RDS 通信?
- php - 如何在没有 laravel 语法的 Laravel 控制器中使用 php 扩展
- c# - 如何通过将不同的参数传递给构造函数来允许实例化不同的单例类
- ios - 支持 CocoaPod 和 Carthage
- javascript - this.state 在 .map 内为 0
- java - java.lang.NoClassDefFoundError: com.google.android.gms.common.internal.zzbo
- c - 如何水平移动星形图案?
- python - TypeError:在 Python2.7 中创建空字典时,'dict' 对象不可调用