한동안 아래 코드를 사용해 왔지만 지금은 오류가 발생합니다.
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
diff
0
파일에 차이가 없으면 성공()이 반환됩니다. 필요에 따라 논리를 조정하십시오.
가능하면 명령의 종료 상태를 테스트하는 것이 명령 대체를 통해 출력을 검사하거나 구문 분석하는 것보다 거의 항상 바람직합니다.
"$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}"
첫째, 나중에 돌아가서 코드를 수정할 때 따옴표나 중괄호가 없으면 실패할 수 있는 작업을 수행하는 것이 훨씬 더 안전합니다.