【问题标题】:Command-substitution breaks quoted arguments with spaces [duplicate]命令替换用空格分隔引用的参数[重复]
【发布时间】:2017-03-10 21:27:49
【问题描述】:

如下所示,命令替换改变了引用的命令行参数的解释。幕后发生了什么,是否有解决方法?

$ cat dumpargs.sh
#! /usr/bin/env bash
for i in "$@"
   {
   echo "$i"
   }

$ cat testfile.txt 
'1 space' '2  space'

$ ./dumpargs.sh $(cat testfile.txt) ## produced undesired output
'1
space'
'2
space'

$ ./dumpargs.sh '1 space' '2  space' ## produces desired output
1 space
2  space

【问题讨论】:

  • shellcheck.net 会为您发现您的问题(缺少引用导致字符串拆分)。尽管期望 literal 引号(不会影响字符串拆分)将被视为 syntactic 引号(会)可能是一个更大的问题。
  • 这也和BashFAQ #50密切相关。
  • 简答,使用xargscat testfile.txt |xargs ./dumpargs.sh
  • 我建议跳过cat——直接从文件中读取比从从文件读取的单独程序写入的FIFO更有效。因此,<testfile.txt xargs ./dumpargs.shxargs ./dumpargs.sh <testfile

标签: bash command-line-arguments command-substitution


【解决方案1】:

当您在命令行上写 ./dumpargs.sh '1 space' '2 space' 时,shell 在将参数传递给脚本之前会解释单引号。参数#1 的值为1 space,参数#2 的值为2 space。单引号不是值的一部分。

当你写./dumpargs.sh $(cat testfile.txt)时, shell 不会尝试解释testfile.txt 的内容。 shell 只解释在命令行输入的实际文本。 像这个示例这样的替代内容,或者例如变量的值不会被解释,而是按字面意思使用。 最后,shell 使用IFS 中的分隔符在命令行上对字符串执行分词。 所以单引号将按字面意思使用, 并且内容只是由空格分隔。

一种可能的解决方法是每行存储一个参数,不带单引号,并使dumpargs.sh 从标准输出中获取参数:

while read -r line; do
    echo "$line"
done

您可以使用./dumpargs.sh < testfile.txt 调用它。

【讨论】:

  • 您的解决方法不是我想要的,但我很欣赏 cmets 关于在不同用法下对事物的解释方式的差异。与 Bash 字符串处理相关的一切都让我摸不着头脑,这让我有点明白了。
猜你喜欢
  • 2018-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-21
相关资源
最近更新 更多