2016-12-04 2 views
1

У меня есть трубопровод Баш команд, выглядит следующим образом:Неожиданный удар со ссылкой на поведение

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" 

Это именно то, что я ожидал. Если я копирую и вставляю одну из этих команд, они делают именно то, что я хочу, чтобы они делали. Теперь я не хочу печатать эти команды, но напрямую их выполнять. Однако, как только я удаляю echo из команды xargs, он не работает. «Это не работает» означает, что свойство неправильно передано градиенту.

Чтобы отладить эту проблему, я попытался добавить | bash -x в мой конвейер, который выявил проблему, но я не знаю, как ее решить.
прилагая это дает следующий результат в первой строке:

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

Я полагаю, проблема в том, что bash по какой-то причине я не знаю, помещает аргументы в кавычки и присоединяет их $. Если я выполняю команду точно так, как она напечатана здесь, то такая же ошибка возникает, как если бы я допустил, что xargs непосредственно запускает команду.

Что мне нужно изменить, чтобы команды выполнялись точно так, как они печатаются, когда я добавляю echo в команду xargs?

Here является report.json файл, если кто-то хочет, чтобы воспроизвести это локально и jq можно скачать here.

Gradle не требуется воспроизвести эту проблему, так как выполнение команды в папке без gradlew файла просто дает:

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

, который по-прежнему демонстрирует проблему.

Я не уверен, в чем проблема, поэтому, если есть лучшее название, не стесняйтесь его менять.

+1

Обратите внимание на символ '\ r'. Вы должны попробовать dos2unix в своем исходном файле. –

+0

Вы правы! Удаление команды '\ r' позволяет выполнить ее корректно. –

+2

«ставит аргументы в кавычки и добавляет их с помощью $». это отладочный вывод из оболочки. (ksh делает то же самое).Оболочка должна нормализовать все dbl-кавычки, одиночные кавычки, переменные, cmd-substitution ouput ", Это всего лишь способ отображения того, что является результатом переменных, cmd-sub, single & dbl цитируемых строк.' \ r' тоже подозрительно для меня ;-). Удачи. – shellter

ответ

3

$'' is a valid way of quoting strings in Bash. Он используется, потому что xtrace экранирует строки, если необходимо, для печати точной команды, которая была запущена. Вы получаете такой же результат, если вы пытаетесь printf '%q\n' "$something", где something содержит специальные символы, такие как символ новой строки, табуляция, забой и т.д.

\r не будет виден, если смотреть на выход в какой-то редактор/терминал, который не делает бежать специальные символы. Например, если вы открываете файл с \r в конце строк, он просто показывает [dos] в нижней части окна, чтобы указать, что разделителем строк является \r\n (стандарт DOS/Windows), а не \n (стандарт * nix).