if [ -n $diffCurr ] 오류: 매개변수가 너무 많습니다.

if [ -n $diffCurr ] 오류: 매개변수가 너무 많습니다.

한동안 아래 코드를 사용해 왔지만 지금은 오류가 발생합니다.

java Editor < "input/editor$i.in" > "tmp/editor$i.out"
diffCurr="$(diff "tmp/editor$i.out" "output/editor$i.out")"
if [ -n $diffCurr ]

오류(위 코드 조각의 마지막 줄에서 발생):

[: 인수가 너무 많습니다.

뭐가 문제 야? diff 결과가 비어 있는지(즉, 파일의 내용이 동일한지) 테스트하려고 합니다.

답변1

diff의 종료 상태에 따라 파일이 다른지 알 수 있으므로 의 출력을 변수에 넣을 필요가 없습니다 diff.

if diff -q file1 file2 >/dev/null 2>&1; then
        # files are equal
else
        # files differ, or an error occurred
fi

diff0파일에 차이가 없으면 성공()이 반환됩니다. 필요에 따라 논리를 조정하십시오.

가능하면 명령의 종료 상태를 테스트하는 것이 명령 대체를 통해 출력을 검사하거나 구문 분석하는 것보다 거의 항상 바람직합니다.

"$diffCurr"완전성을 기하기 위해 원래 예제는 해당 줄에 따옴표가 없기 때문에 실패합니다 if. 따라서 "단어 분리"를 여러 단어로 진행하므로 "인수가 너무 많습니다".

답변2

jw013 말이 맞습니다. 어차피 이 줄은 필요하지 않습니다.

그러나 실제 질문에 답하기 위해 전달한 변수 test( 라고도 함 [) 주위의 따옴표를 생략했습니다.

즉, 변수가 비어 있으면 매개변수가 없는 것과 같고(예: [ -n ]), 변수에 공백이 있으면 여러 매개변수를 전달한 것과 같습니다(그렇게 된 것 같습니다).

문자열은 항상 test따옴표로 묶습니다. 예를 들면 다음과 같습니다.

if [ -n "$myvar" ]

답변3

diff테스트 출력보다 명령의 종료 코드를 테스트하는 것이 더 나을 것 입니다.

diffCurr="$(diff "tmp/editor$i.out" "output/editor$i.out")"
if [ $? -ne 0 ]; then  # different
...

출력에 관심이 없다면 jw013의 제안을 따를 수 있습니다.

답변4

위의 좋은 답변 외에도 bash와의 사랑/증오 관계는 매개 변수 대체의 강점을 중심으로 하며 원할 때 대체를 중지하는 것이 매우 어려울 수 있다는 사실은 특히 변수를 사용할 때 더욱 그렇습니다. 한 번 이상.

따라서 저는 거의 항상 다음과 같은 변수 참조를 인코딩합니다.

A="${B}"

이렇게 하면 B단일 문자열(가장 일반적으로 내가 원하는 것)로 처리되고 다음과 같은 작업이 가능해집니다.

A="${B}foo"

그리고 중괄호 안에서만 작동하는 다른 멋진 옵션도 있습니다.

간단한 안전 변수 참조를 다음과 같이 인코딩하면

A="${B}"

첫째, 나중에 돌아가서 코드를 수정할 때 따옴표나 중괄호가 없으면 실패할 수 있는 작업을 수행하는 것이 훨씬 더 안전합니다.

관련 정보