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>扱われます。しかし、2番目のスクリプトでは、コードの連続がコメントであり、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

これは私の知能ではありません。これはマルワンアルサバーグの。詳しくは下記リンクをご覧ください。

複数行コマンドに行コメントを追加する方法

おすすめ記事