Por que comentar essa linha em um script de shell (usando o pdftk) causa problemas?

5

Considere o seguinte script de shell simples (usando 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

Agora, se eu comentar uma linha, a loucura ocorre. Aqui está o script modificado.

#!/bin/sh

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

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

A saída é semelhante a:

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

Alguém pode explicar por que há um problema ao fazer isso? Eu assumi que sh (ou bash , não faz diferença) simplesmente ignoraria essa linha e seguiria em frente.

Além disso, há algo semelhante que eu possa fazer que funcione? Quando eu uso pdftk , eu passo uma lista de arquivos, alguns dos quais eu posso querer comentar ou descomentar de tempos em tempos.

Estou usando o pdftk 2.02-2 no Debian 8.2 (jessie).

Reprodutor mínimo para esses questionamentos sobre o comportamento:

$ cat test.sh
#!/bin/sh
echo \
    A \
#   B \
    C
$ ./test.sh
A
./test.sh: line 5: C: command not found
    
por Faheem Mitha 03.01.2016 / 10:26

1 resposta

8

A causa

Primeiramente, vamos dar uma olhada na página de manual do bash:

A non-quoted backslash () is the escape character. It preserves the literal value of the next character that follows, with the exception of . If a \<newline> pair appears, and the backslash is not itself quoted, the \<newline> is treated as a line continuation (that is, it is removed from the input stream and effectively ignored).

Então, quando você usa \ antes de um <newline> , ele trata como uma continuação de linha. Mas no seu segundo script, a continuação do seu código após A=blank.pdf é um comentário, e como \ após B=blank.pdf também faz parte do seu comentário, ele não causa continuação de linha. Como resultado, o restante do seu script será tratado como outro comando exclusivo. Então o bash vai pensar no seu script como algo assim:

#!/bin/sh

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

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

Aqui, você provavelmente receberá um erro dizendo algo como C=blank.pdf: command not found .

Backticks para o resgate!

No entanto, você pode usar comentários entre suas continuações de linha, usando o recurso de substituição de comandos de backticks, como este:

#!/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

Esta não é a minha ingenuidade. É Marwan Alsabbagh . Veja o seguinte link para mais detalhes:

Como colocar um comentário de linha para um Multi- linha de comando

    
por 03.01.2016 / 11:10