배열에서 가장 작은 숫자를 확인하는 C 프로그램이 있습니다. 이 프로그램을 실행하고 이에 대한 테스트 사례를 제공하는 스크립트가 있지만 다음 줄의 의미를 파악하는 데 어려움을 겪고 있습니다.
if ! diff -u <(echo "1 2 5" | $PROGRAM) <(echo 1); then
echo "test failed on 1 2 5"
((FAILURES++))
fi
diff
따라서 파일을 비교하는 방법을 알고 있으며 -u
타임스탬프, 어떤 파일에서 어떤 줄이 제거되었는지, 어떤 파일에 어떤 줄이 추가되었는지 등이 표시됩니다. 하지만 에코 뒤의 "<" 부분에서 무슨 일이 일어나고 있는지 이해할 수 없는 것 같습니다. 나는 괄호 안의 (echo "1 2 5" | $PROGRAM) 여기서 PROGRAM이 C 프로그램을 실행하는 파일이고 내 프로그램이 최소한의 올바른 출력을 얻지만 여전히 test failed on 1 2 5를 인쇄한다는 것을 알고 있습니다. if 문의 표현을 이해하지 못하기 때문에 이유를 이해하지 못합니다.
답변1
이 두 <(cmd1)
<(cmd2)
매개변수는 나에게 새로운 것이지만 분명히 fifo라는 이름의 경로로 대체되어 작성 cmd1
되었습니다 cmd2
. man bash(1)에서:
Process Substitution
Process substitution is supported on systems that support named
pipes (FIFOs) or the /dev/fd method of naming open files. takes
the form of <(list) or >(list). The process list is run with its
input or output connected to a FIFO or some file /dev/fd. The
name of this file is passed as an argument to the current command
as the result of the expansion. If the form is used, writing to
the file will provide input for list. If the <(list) form is
used, the file passed as an argument be read to obtain the output
of list.
이 테스트는 fifo 이름을 보여줍니다.
echo <(date) <(sleep 1; date)
/dev/fd/63 /dev/fd/62
그러면 fifo를 읽은 결과가 인쇄됩니다.
cat <(date) <(sleep 1; date)
Fri Feb 23 14:23:41 PST 2018
Fri Feb 23 14:23:42 PST 2018
답변2
아무도 질문에 대답하지 않았기 때문에("이 코드 줄에 무슨 일이 일어나고 있나요?" - "이 코드 줄이 무엇을 의미하는지 알아내려고 노력 중입니다."):
이 스크립트는 C 프로그램을 테스트하고 있습니다. 그것이하는 일은 기본적으로 다음과 같습니다
# Run the program with input “1 2 5” and write its output to a file. Since the program
# is supposed to check the input for the minimum number, we expect it to output “1”.
echo "1 2 5" | $PROGRAM > file1
# Create a second file that contains the known correct output (minimum)
# for this input (i.e., “1”).
echo 1 > file2
# Compare the files. diff’s standard output and standard error will go to the stdout
# and stderr of the script, which is the terminal unless the user does I/O redirection.
# The `if` will test diff’s exit status.
if diff -u file1 file2
then
# Exit status 0 means the files are identical;
# i.e., the program’s output is correct; i.e., the test passes. Do nothing.
:
else
# Exit status non-zero (probably 1) means that the files are different;
# i.e., the program’s output is wrong; i.e., the test fails.
echo "test failed on 1 2 5"
((FAILURES++))
fi
rm file1 file2
대본은 왜 이렇게 작성됐나요?
아주 좋은 질문입니다. 어쩌면 스크립트 작성자에게 물어보고 답변을 우리에게 전달할 수도 있습니다.
파일을 사용할 필요가 없습니다. 그리고 그들은 파일을 사용하지 않습니다. 그들은 다음과 같습니다앤디 달튼그리고노벡이미 설명했습니다. 프로세스 대체를 사용하십시오. 이것은 파이프이며 POSIX와 호환되지 않습니다. 예, 프로그램의 출력을 캡처하려면 파일이나 파이프를 사용해야 합니다. 그러나 올바른 출력을 저장하기 위해 파일이나 파이프가 필요하지 않습니다. 스크립트를 다시 작성할 수 있습니다.
if [ "$(echo "1 2 5" | $PROGRAM)" != 1 ] then echo "test failed on 1 2 5" ((FAILURES++)) fi
그것은주문하다프로그램의 출력을 캡처한 다음 올바른 출력을
if
명령줄에 넣으려면 바꾸기를 사용하세요.-u
옵션을 사용하는 이유는 무엇입니까diff
?- 이 옵션은 "통합 컨텍스트의 NUM(기본값 3)줄 출력"으로 문서화되어 있습니다. 즉, 길이가 100줄인 두 개의 파일이 있고 42행을 제외하고 동일하다면
diff -u
39-45행이 표시됩니다(위 3줄, 아래 3줄 서로 다름). 그러나 입력 중 하나의 길이가 한 줄인 것으로 알려져 있고 다른 입력의 길이도 한 줄인 것으로 예상되는 경우 이는 의미가 없습니다. -u
옵션의 문서화되지 않은 기능은diff
입력 수정 시간을 표시한다는 것입니다. 그러나 지정된 스크립트에서 입력은diff
동적으로 생성된 파이프인 프로세스 대체입니다. 따라서 각 콘텐츠의 수정 시간은 현재 시간, 즉 화면상의 혼잡한 시간이 됩니다.
- 이 옵션은 "통합 컨텍스트의 NUM(기본값 3)줄 출력"으로 문서화되어 있습니다. 즉, 길이가 100줄인 두 개의 파일이 있고 42행을 제외하고 동일하다면
"$PROGRAM"
특별한 이유가 없는 한 항상 쉘 변수(예: )를 인용해야 합니다 .
스크립트에서 프로그램이 실패했다고 보고하는 이유는 무엇입니까?
프로그램이나 적어도 그 출력을 보지 않고는 알 수 없습니다. 프로그램 출력에 \r
개행 문자 대신 또는 그에 추가하여 공백이나 캐리지 리턴( )이 포함될 수 있습니까 ? 아니면 추가 줄바꿈(예: 빈 줄)을 추가할 수도 있나요? 이 작업을 수행
에코 "1 2 5" |귀하의 프로그램OD 택시(
od
모든 옵션을 인식하지 못한다고 보고하는 경우 불만을 표시하는 옵션(예: -cb
또는 )을 무시하십시오 -ab
.) 물론 출력은 a 1
및 줄 바꿈( \n
)이어야 합니다.
답변3
이 코드 줄은 다음 질문에 답합니다. $PROGRAM 변수로 정의된 프로그램이 값 1을 반환하여 "1 2 5" 입력에 응답합니까? 이는 작업을 수행하는 데 있어 매우 혼란스러운 방법입니다. 다음과 같이 작성할 수 있습니다.
if [ $(echo "1 2 5" | $PROGRAM) -ne 1 ] ; then
두 번째 질문을 첫 번째 질문에 병합했습니다(그런데, 검색은 하지만 묻지 않는 다른 사람들이 더 쉽게 할 수 있도록 각 질문에 대해 별도의 질문 페이지를 만들어야 합니다). 성공해야 한다고 생각하는 것에도 불구하고 실패 표시를 받는 이유는 아마도 (개인 경험에 비추어 어둠 속에서 촬영하는 것) 때문일 것 $PROGRAM
입니다 1
.