Bash 스크립트: 문자열에 작은따옴표를 추가하지 마세요.

Bash 스크립트: 문자열에 작은따옴표를 추가하지 마세요.

한 함수의 출력을 다른 함수에 전달하려고 합니다.

set -x
OUTPUT=$(git diff --name-only --diff-filter=AM develop... | sed 's/.*/"&"/')
./bin/phpcs $OUTPUT

내 주요 문제는 첫 번째 함수가 파일 목록을 반환하고 파일에 공백이 포함될 수 있다는 것입니다. 그래서 큰따옴표로 묶었는데, 다른 함수에 전달하면 작은따옴표가 추가됩니다.

산출:

++ git diff --name-only --diff-filter=AM develop...
++ sed 's/.*/"&"/'
+ OUTPUT='"test file.php"
"testfile.php"'
+ ./bin/phpcs '"test' 'file.php"' '"testfile.php"'

호출의 주요 최종 목표는 다음과 같습니다.

./bin/phpcs "test file.php" "testfile.php"

답변1

문제는 출력되는 텍스트에 큰따옴표를 추가한다는 것입니다 git diff. 이로 인해 경로 이름이 깨지고 파일 목록을 올바르게 구문 분석하기가 더 어려워집니다. 특히 경로 이름에 따옴표가 포함된 경우 더욱 그렇습니다.

추적 출력에 표시되는 작은따옴표는 bash문자열이 어떻게 구분되는지 더 쉽게 볼 수 있도록 추가되었습니다(예: "test, file.php", 및 "testfile.php"가 세 개의 개별 매개변수임을 표시하기 위해). 쉘의 추적 출력은 쉘이 수행하는 작업에 대한 힌트를 제공하기 위한 디버그 출력이며 일반적으로 그렇지 않습니다.실제쉘에 의해 실행되는 코드입니다.


내보낸 경로 이름을 안전하게 사용하려면 git diff --name-only-z옵션을 사용하는 것이 좋습니다. 이로 인해 git경로 이름이 빈 구분 목록으로 출력됩니다. 그런 다음 이를 사용하여 xargs -0이 목록의 요소에 대해 명령을 수행할 수 있습니다.

git diff --name-only -z --diff-filter=AM develop... |
xargs -0 ./bin/phpcs

파일 목록을 배열로 읽을 수도 있습니다. 예를 들어, bash셸에서 다음과 같습니다.

readarray -d '' -t names < <( git diff --name-only -z --diff-filter=AM develop... )

./bin/phpcs "${names[@]}"

이것은 분명히 git diff출력하지 않는 것에 달려 있습니다.이름이 너무 많아.

답변2

파일 이름에 개행 문자가 포함되어 있지 않다고 보장할 수 있는 경우 이를 사용하여 파일 이름을 구분하고 배열로 팝할 수 있습니다.

OIFS=$IFS IFS=$'\n'
files=( $(git diff --name-only --diff-filter=AM develop...) )
IFS=$OIFS

이제 배열을 인용된 문자열 목록으로 삽입할 수 있습니다.

./bin/phpcs "${files[@]}"

shPOSIX 또는 .NET에서는 작동하지 않습니다 . 배열을 지원하는 셸을 dash사용해야 합니다.bash

답변3

작은따옴표를 추가하지 마세요. bash -x어떤 리터럴 매개변수가 표시되는지 보여줍니다. 인용되지 않은 것처럼 $OUTPUT토큰화는 공백과 개행에서 작동합니다. 이는 "변수의 일부이며 쉘 구문 분석과 관련이 없습니다.

다음을 수행할 수 있습니다.

eval ./bin/phpcs $OUTPUT

그러나 roaima의 배열 접근 방식이 더 나은 것 같습니다.

관련 정보