pdftk를 사용하여 쉘 스크립트에서 이 줄을 주석 처리하면 문제가 발생하는 이유는 무엇입니까?

pdftk를 사용하여 쉘 스크립트에서 이 줄을 주석 처리하면 문제가 발생하는 이유는 무엇입니까?

다음과 같은 간단한 쉘 스크립트를 고려하십시오( 사용 pdftk).

#!/bin/sh    
echo "" | ps2pdf -sPAPERSIZE=a4 - blank.pdf

pdftk \
    A=blank.pdf \
    B=blank.pdf \
    C=blank.pdf \
    cat A C \
    output foo.pdf

이제 한 줄을 주석 처리하면 이상한 일이 발생합니다. 수정된 스크립트입니다.

#!/bin/sh

echo "" | ps2pdf -sPAPERSIZE=a4 - blank.pdf

pdftk \
    A=blank.pdf \
#   B=blank.pdf \
    C=blank.pdf \
    cat A C \
    output foo.pdf

출력은 다음과 같습니다.

Done.  Input errors, so no output created.
cat: A: No such file or directory
cat: C: No such file or directory
cat: output: No such file or directory
%PDF-1.4
%<E2><E3><CF><D3>
4 0 obj 
<<
/Filter /FlateDecode
/Length 23
>>
stream
x<9C>+T0<D0>3T0^@A(<9D><9C><CB>^U<C8>^E^@5I^De
endstream 
endobj 
3 0 obj 
<<
/Resources 
<<
/ProcSet [/PDF]
>>
/Type /Page
/Parent 1 0 R
/Contents 4 0 R
/MediaBox [0 0 595 842]
>>
endobj 
7 0 obj 
<<
/Filter /FlateDecode
/Length 23
>>
stream
x<9C>+T0<D0>3T0^@A(<9D><9C><CB>^U<C8>^E^@5I^De
endstream 
endobj 
6 0 obj 
<<
/Resources 
<<
/ProcSet [/PDF]
>>
/Type /Page
/Parent 1 0 R
/Contents 7 0 R
/MediaBox [0 0 595 842]
>>
endobj 
1 0 obj 
<<
/Kids [3 0 R 6 0 R]
/Type /Pages
/Count 2
>>
endobj 
9 0 obj 
<<
/Type /Catalog
/Pages 1 0 R
>>
endobj 
10 0 obj 
<<
/ModDate (D:20160103144953+05'30')
/CreationDate (D:20160103144953+05'30')
/Creator (pdftk 2.02 - www.pdftk.com)
/Producer (itext-paulo-155 \(itextpdf.sf.net-lowagie.com\))
>>
endobj xref
0 11
0000000000 65535 f 
0000000455 00000 n 
0000000000 65535 f 
0000000112 00000 n 
0000000015 00000 n 
0000000000 65535 f 
0000000332 00000 n 
0000000235 00000 n 
0000000000 65535 f 
0000000520 00000 n 
0000000571 00000 n 
trailer

<<
/Info 10 0 R
/ID [<cd7858cb595d5fbe3dd38c1258972091><390fa471e3236a790d9231e931a73695>]
/Root 9 0 R
/Size 11
>>
startxref
767
%%EOF

이것이 왜 문제를 일으키는지 설명할 수 있는 사람이 있습니까? 나는 그 줄을 무시하고 계속 진행하는 것이 좋다고 sh생각 합니다.bash

또한 비슷한 일을 할 수 있습니까? 나는 그것을 사용할 때 pdftk파일 목록을 전달하는데, 그 중 일부는 때때로 주석을 달거나 주석을 제거하고 싶을 수도 있습니다.

pdftk저는 Debian 8.2(jessie)에서 2.02-2를 사용하고 있습니다.


이 동작에 대해 궁금한 분들을 위해 최소 재생산:

$ cat test.sh
#!/bin/sh
echo \
    A \
#   B \
    C
$ ./test.sh
A
./test.sh: line 5: C: command not found

답변1

이유

먼저 bash 매뉴얼 페이지를 살펴보겠습니다:

따옴표가 없는 백슬래시()는 이스케이프 문자입니다. 제외하고 다음 문자의 리터럴 값을 유지합니다.\<newline> 쌍이 발생하고 백슬래시 자체가 인용되지 않은 경우 \<newline>은 줄 연속으로 처리됩니다.(즉, 입력 스트림에서 제거되어 사실상 무시됩니다.)

\따라서 a 앞에 사용하면 <newline>연속 줄로 처리됩니다. 그러나 두 번째 스크립트에서는 코드의 연속이 A=blank.pdf주석이고 \그 뒤의 B=blank.pdf코드도 주석의 일부이기 때문에 줄이 계속되는 것은 아닙니다. 따라서 스크립트의 나머지 부분은 또 다른 고유한 명령으로 처리됩니다. 따라서 bash는 스크립트가 다음과 같다고 생각할 것입니다.

#!/bin/sh

echo "" | ps2pdf -sPAPERSIZE=a4 - blank.pdf

pdftk A=blank.pdf #   B=blank.pdf \
C=blank.pdf cat A C output foo.pdf

여기에서 비슷한 오류 메시지를 받게 될 가능성이 높습니다 C=blank.pdf: command not found.

구조에 백틱!

그러나 다음과 같이 역따옴표를 사용하는 명령 대체 기능을 통해 줄 연속에서 주석을 사용할 수 있습니다.

#!/bin/sh

echo "" | ps2pdf -sPAPERSIZE=a4 - blank.pdf

pdftk \
    A=blank.pdf \
`#  B=blank.pdf` `#You added left-side comment and I added this comment and everything is awesome` \
    C=blank.pdf \
    cat A C \
    output foo.pdf

이것은 내 지능이 아닙니다. 이것은마르완 알사바그의. 자세한 내용은 아래 링크를 참조하세요.

여러 줄 명령에 줄 주석을 추가하는 방법

관련 정보