Bash中的嵌套引号

时间:2017-11-23 14:02:55

标签: bash shell quotes

请让我用一些示例脚本解释我的场景,该脚本比我的实际应用程序简单得多,但显示相同的行为:

对于演示,我使用了两个bash shell脚本。第一个叫argtest.sh,只输出命令行参数:

#/bin/bash

echo "Argument 1: $1"
echo "Argument 2: $2"

测试:

root@test:~# ./argtest.sh 1 2
Argument 1: 1
Argument 2: 2

root@test:~# ./argtest.sh "1 2" 3
Argument 1: 1 2
Argument 2: 3

这可以按预期工作

我已经创建了另一个命令:

./argtest.sh $(for i in ` seq 1 2 ` ; do echo Number $i; done) 

这是结果

Argument 1: Number
Argument 2: 1

我在Number周围尝试了许多不同的引号组合(")和转义引号(\"),但没有组合产生所需的输出:

Argument 1: Number 1
Argument 2: Number 2

如何获得该输出?

4 个答案:

答案 0 :(得分:4)

你做不到。命令替换受到分词的影响。它的输出是两行

Number 1
Number 2

但在分词期间,换行符被视为任意空格。因此,命令替换分为4个单词(Number1Number2),每个单词都是{{1}的单独参数}}

在分词过程中,字面上会对其他引号进行处理;像argtest.sh这样的字符串被分为3个字("a b" c"ab"),而不是2(ca b)。

要执行您想要的操作,您需要使用c循环从循环中一次读取一行输出。例如:

while

答案 1 :(得分:2)

正如chepner所提到的,命令替换受到分词的影响。

以下几个例子可以更好地理解这个

使用echo替换printf并转义双引号时的行为如下: -

for i in ` seq 1 2 ` ; do printf "\"Number %d\" " "$i"; done; printf "\n"
"Number 1" "Number 2"

./arg.sh  $(for i in ` seq 1 2 ` ; do printf "\"Number %d\" " "$i"; done; printf "\n")
Argument 1: "Number                                                                   
Argument 2: 1"     

现在,如果我尝试用双引号括起整个命令替换,它会将它们视为一个单独的参数: -

./arg.sh "$(for i in ` seq 1 2 ` ; do printf "\"Number %d\" " "$i"; done; printf "\n")"
Argument 1: "Number 1" "Number 2"                                                                                                                         
Argument 2:                                                                                                                                                                      

答案 2 :(得分:2)

因为论据需要分词,您可以更改$IFS并将新分隔符放入echo

IFS=$'_\n'
./argtest.sh $(for i in {1..2} ; do echo "Number ${i}_"; done )

不要忘记恢复旧的$ IFS

oIFS=$IFS
...
IFS=$oIFS

btw {1..2}相当于seq 1 2,但您不需要外部命令

答案 3 :(得分:1)

您可以使用for i in ` seq 1 2 ` ; do echo Number $i; done | xargs -d $'\n' ./argtest.sh

section {
  display: flex;
  flex-wrap: wrap;
}
article {
  box-sizing: border-box;
  border:1px solid grey;
  width: 100%;
  height: 50px;
}

@media (min-width: 500px) {
  section {
    flex-direction: column;
  }
  article {
    width: 50%;
  }
   article:nth-child(even) {
     order: 2;
   }
   article:nth-child(2) {
     /* this breaks into the second column after the 2nd child
     (which is not the first element of the second half of elements) */
     page-break-before: always;
   }
}

/* just for demo */  
article:first-child {
  height: 66px;
  background-color: #e0e0fe;
}
article:nth-child(4) {
  height: 80px;
  background-color: #aee0e0;
}
article:nth-child(6) {
  height: 130px;
  background-color: yellow;
}