Reputation: 1462
I have a pipeline of bash commands that looks like this:
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
The output of this command is:
./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"
This is exactly what I am expecting. If I copy and paste one of these commands, they do exactly what I want them to do. Now I don't want to print these commands but directly execute them. However, as soon as I remove the echo
from the xargs
command, it doesn't work. "It doesn't work" means that the property is not correctly passed to gradle.
In order to debug this issue, I tried to append | bash -x
to my pipeline which revealed the issue but I don't know how to solve it.
Appending this yields the following output as the first line:
+ ./gradlew clean test $'-PdependencyOverrides=org.flywaydb:flyway-core:4.0.3\r'
I assume, the problem is that bash
for some reason I don't know puts the arguments in quotes and prepends them with $
. If I execute the command exactly as it is printed here, the same error occurs as if I let xargs
directly run the command.
What do I have to change so the commands are executed exactly the way they are printed when I add the echo
to the xargs
command?
Here is the report.json
file if anyone wants to reproduce this locally and jq
can be downloaded here.
Gradle is not needed to reproduce this problem, as executing the command in a folder without a gradlew
file just yields:
+ ./gradlew clean test $'-PdependencyOverrides=org.flywaydb:flyway-core:4.0.3\r'
bash: line 1: ./gradlew: No such file or directory
which still demonstrates the problem.
I am not sure what the exact problem is, so if there is a better title feel free to change it.
Upvotes: 1
Views: 48
Reputation: 58958
$''
is a valid way of quoting strings in Bash. It's being used because xtrace
escapes strings if necessary to print the exact command which was run. You get the same kind of result if you try to printf '%q\n' "$something"
, where something
contains special characters like newline, tab, backspace, etc.
\r
won't be visible when you look at output in some editor/terminal which does not escape special characters. For example, if you open a file with \r
at the end of lines it will simply show [dos]
at the bottom of the window to indicate that the line separator is \r\n
(DOS/Windows standard) rather than \n
(*nix standard).
Upvotes: 3