2016/03/05

ヒアドキュメントをインデントする方法

このブログ、年に1、2度しか更新してませんが折角作ったんだから有効活用してみようということであれこれ書いてみようかなと。

ファイルが作成されていれば「SUCCESS」失敗していれば「FAILED」とログファイルに書き出すという、よくあるシェルスクリプトをこんな感じで作成していました。


if [ -e "${FILE}" ]; then

  cat <<; EOF >> file_check.log
  ##################
  #       SUCCESS        #
  ##################
  EOF

else

  cat < EOF >> file_check.log
  ##################
  #       FAILED           #
  ##################
  EOF

#
#わかりにくいですが、cat~EOFまで半角スペースでインデントしています。
#以下処理部分につき省略…
#


一通り書き終えて実行したところ、以下のようなエラーが…。


/home/foo/bar.sh: line **: warning: here-document at line ** delimited by end-of-file (wanted `EOF')
/home/foo/bar.sh: line **: syntax error: unexpected end of file


oh...( ‘ᾥ’ )
慌てず騒がずbashのmanを読んでみます。

Here Documents

       This  type  of  redirection  instructs the shell to read input from the
       current source until a line containing only delimiter (with no trailing
       blanks)  is seen.  All of the lines read up to that point are then used
       as the standard input for a command.

       The format of here-documents is:

              <<[-]word
                      here-document
              delimiter

       No parameter expansion, command substitution, arithmetic expansion,  or
       pathname expansion is performed on word.  If any characters in word are
       quoted, the delimiter is the result of quote removal on word,  and  the
       lines  in the here-document are not expanded.  If word is unquoted, all
       lines of the here-document are subjected to parameter  expansion,  com-
       mand  substitution,  and arithmetic expansion.  In the latter case, the
       character sequence \ is ignored, and \ must be used  to  quote
       the characters \, $, and `.

《訳》
ヒアドキュメント

このタイプのリダイレクトはshellに対し、終端文字(※末尾に空白文字を持たない)のみが含まれる行が見つかるまで現在の入力ソースを読み込む指示となります。すべての行は終端文字の地点まで、コマンドに標準入力として渡されます。

ヒアドキュメントのフォーマットは以下の通り:

              <<[-]word
                      here-document
              delimiter

パラメータの展開、コマンドの置換、算術式の展開、またはパス名の展開は、wordに対しては実行されません。wordのいずれかの文字がクォートされている場合、delimiterはwordのクォートを消去する結果となり、ヒアドキュメントの行内では展開が行われません。 wordがクォートされていない場合は、ヒアドキュメント内のすべての行はパラメータの展開、コマンドの置換、算術式の展開を施されます。後者の場合、文字列の\は無視され、文字列\, $, `,を使う場合は\でクォートされなければなりません。

予感はしていましたが、インデントに使った半角スペースが文字列として認識されてしまい終端文字が見つからねえぞコンチキショウ!という事態になっていたようです。では、インデントを使いたい場合はどうすれば良いのかというと、ちゃんと続きの行に回答がありました。

       If the redirection operator is  <<-, then all leading tab characters are
       stripped from input lines and  the  line  containing  delimiter.   This
       allows  here-documents within shell scripts to be indented in a natural
       fashion.

《訳》
リダイレクト演算子を"<<-"とした場合は、終端文字列を含む行までのすべてのタブが削除されます。これにより、シェルスクリプト内のヒアドキュメントを自然な方法でインデントすることが出来ます。

( ・ิω・ิ)......なるほど
これを踏まえて冒頭のシェルスクリプトを修繕すると、以下の通りとなるわけですね。


if [ -e "${FILE}" ]; then

     cat < EOF >> file_check.log
     ##################
     #       SUCCESS        #
     ##################
     EOF

else

#
#cat~EOFまでTabでインデントしています。
#以下処理部分につき省略…
#


これでエラーは出なくなりました。なにごとも日々勉強です。

0 件のコメント:

コメントを投稿

認証のためのCAPTCHAがめんどくさくてごめんね(´・ω・`)