在命令替换中正确使用引号 - 如何?

问题描述 投票:0回答:2

在一个相当大的项目中,我遇到了以下问题:在 bash 脚本中计算正确的命令时,我无法使脚本尊重带有空白的单个参数所需的双引号。

$ ./testo "two three"
ls -l "two three_DD_FF"  # <- Why does it look for two files HERE??
ls: cannot access '"two': No such file or directory
ls: cannot access 'three_DD_FF"': No such file or directory

“二三”是单一参数。

使用 Two_Three 我的代码可以正常工作,正如预期的那样:

$ ./testo two_three
ls -l "two_three_DD_FF"
ls: cannot access '"two_three_DD_FF"': No such file or directory

这是我能想到的基本通用代码:

#!/usr/bin/bash
cmd="ls -l"
trio=""'"'"${1}_DD"
trio="${cmd} ${trio}_FF"'"'""
echo ${trio}
${trio}

(对于看起来奇怪的强引用,我没有找到比上面的方法更奇怪的方法,但这不是我在这里主要关心的。)

我不明白的是执行中的问题:

ls -l "two three_DD_FF"
尽管有双引号,上面的行仍然会导致搜索 two 文件;而命令提示符上的 same 行则按预期完成工作(即搜索文件“
two three_DD_FF"
:

$ ls -l "two three_DD_FF"
-rw-rw-r-- 1 myhome me 0 Aug 27 13:09 'two three_DD_FF'

也就是说,行

echo ${trio}
显示了正确的命令(至少在命令行上执行时;而相同的命令在脚本内执行时会失败。它无法遵守文件名的双引号被搜查。

我的问题:

  1. 为什么同一命令在脚本中会失败?
  2. 当然,如何纠正脚本,以便调用实际上产生正确的输出?
bash double filenames quotes execution
2个回答
0
投票

我的建议:使用数组:

#!/usr/bin/env bash
cmd=(ls -l)
trio=( "${cmd[@]}" "${1}_DD_FF" )
"${trio[@]}"

0
投票

将脚本中的

echo
替换为
xxd <<< ${trio}
,我们可以看到:

00000000: 6c73 202d 6c20 2274 776f 2074 6872 6565  ls -l "two three
00000010: 5f44 445f 4646 220a                      _DD_FF".

您的变量

trio
因此包含字符串
ls -l "two three_DD_FF"

当您运行

${trio}
(可以更简单地写为
$trio
)时,bash 对字符串应用分词,给出以下单词:

0: `ls`
1: `-l`
2: "two
3: three_DD_FF"

因此,使用选项参数 (

ls
) 和两个附加参数
-l
"two
来调用
three_DD_FF"

这反映在关于找不到

"two
three_DD_FF"
的错误消息中。

© www.soinside.com 2019 - 2024. All rights reserved.