意外的 bash 引用行为

  • 本文关键字:引用 bash 意外 bash
  • 更新时间 :
  • 英文 :


我有一个 bash 命令管道,如下所示:

cat report.json | 
./jq '.outdated.dependencies[] |  {group, name, "version": .available.milestone} | .group + ":" + .name + ":" + .version' | 
xargs -0 -d'n' -I DEPENDENCY echo ./gradlew clean test -PdependencyOverrides=DEPENDENCY

此命令的输出为:

./gradlew clean test -PdependencyOverrides="org.flywaydb:flyway-core:4.0.3"
./gradlew clean test -PdependencyOverrides="org.hibernate:hibernate-c3p0:5.2.5.Final"
./gradlew clean test -PdependencyOverrides="org.hibernate:hibernate-core:5.2.5.Final"
./gradlew clean test -PdependencyOverrides="org.hibernate:hibernate-entitymanager:5.2.5.Final"
./gradlew clean test -PdependencyOverrides="org.hibernate:hibernate-java8:5.2.5.Final"
./gradlew clean test -PdependencyOverrides="org.hibernate:hibernate-validator:5.3.3.Final"
./gradlew clean test -PdependencyOverrides="com.fasterxml.jackson.core:jackson-databind:2.8.5"
./gradlew clean test -PdependencyOverrides="com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.8.5"
./gradlew clean test -PdependencyOverrides="javax.el:javax.el-api:3.0.1-b04"
./gradlew clean test -PdependencyOverrides="org.apache.logging.log4j:log4j-api:2.7"
./gradlew clean test -PdependencyOverrides="org.apache.logging.log4j:log4j-core:2.7"
./gradlew clean test -PdependencyOverrides="org.apache.logging.log4j:log4j-slf4j-impl:2.7"
./gradlew clean test -PdependencyOverrides="org.mockito:mockito-core:2.2.28"
./gradlew clean test -PdependencyOverrides="org.postgresql:postgresql:9.4.1212"
./gradlew clean test -PdependencyOverrides="com.getsentry.raven:raven-log4j2:7.8.1"
./gradlew clean test -PdependencyOverrides="com.sparkjava:spark-core:2.5.4"
./gradlew clean test -PdependencyOverrides="org.springframework:spring-jdbc:4.3.4.RELEASE"
./gradlew clean test -PdependencyOverrides="org.springframework.restdocs:spring-restdocs-restassured:1.1.2.RELEASE"

这正是我所期待的。如果我复制并粘贴这些命令之一,它们会完全按照我希望它们执行的操作。现在我不想打印这些命令,而是直接执行它们。但是,一旦我从xargs命令中删除echo,它就不起作用。"它不起作用"表示该属性未正确传递给 gradle。

为了调试此问题,我尝试将| bash -x附加到我的管道中,这揭示了问题,但我不知道如何解决它。
追加此内容将生成以下输出作为第一行:

+ ./gradlew clean test $'-PdependencyOverrides=org.flywaydb:flyway-core:4.0.3r'

我认为,问题是bash出于某种原因,我不知道将参数放在引号中并在它们前面加上$.如果我完全按照此处打印的顺序执行命令,则会发生与xargs直接运行命令相同的错误。

我必须更改什么才能完全按照将echo添加到xargs命令时的打印方式执行命令?

如果有人想在本地重现此文件,这是report.json文件,jq可以在此处下载。

重现此问题不需要 Gradle,因为在没有gradlew文件的文件夹中执行命令只会产生:

+ ./gradlew clean test $'-PdependencyOverrides=org.flywaydb:flyway-core:4.0.3r'
bash: line 1: ./gradlew: No such file or directory

这仍然表明了问题。

我不确定确切的问题是什么,所以如果有更好的标题,请随时更改它。

$''是在 Bash 中引用字符串的有效方法。之所以使用它xtrace是因为如果需要,它会转义字符串以打印运行的确切命令。如果您尝试printf '%qn' "$something",您会得到相同的结果,其中something包含换行符、制表符、退格键等特殊字符。

当您在某些无法转义特殊字符的编辑器/终端中查看输出时,r将不可见。例如,如果您打开一个在行尾带有r的文件,它将只在窗口底部显示[dos],以指示行分隔符是rn(DOS/Windows 标准)而不是n(*nix 标准)。

最新更新