若葉の技術メモ

コンピュータやプログラミングに関して調べたり、取り組んだりしたことをまとめる若葉のノート📓。コンピュータ・プログラミング初めてって方も一緒に勉強していきましょう!初心は大事!いつでも若葉☘のような意気込みで!

  • No.   

若葉の技術メモ

コンピュータやプログラミング・数理に関して調べたり、取り組んだりしたことをまとめる若葉のノート。

コンピュータ・プログラミング・数理が初めてって方も一緒に勉強していきましょう!

初心は大事!いつでも若葉☘のような意気込みで!

【予期せぬシンタックスエラー!?】Shell Scriptでコメントアウトする方法!

f:id:wakaba-mafin:20181118205651j:plain:w150:right

ちょこっとした作業の際に便利なShell Script。

ファイルの一括操作や面倒な処理の自動化などいろんな用途で活用することができます!

ですが、このシェルスクリプトコメントアウトする際に気をつけてないと思わぬ罠に嵌ってしまうことがあります💦

ということで、今回の記事ではシェルスクリプトにおいて複数行コメントアウトする方法その際に気を付けることの二点をお伝えします!


はじめに

ターミナル上で作業するのに欠かせない各種コマンド。 LinuxMacなどで欠かせません。

ですが、コマンドを一個一個対話的に打っていくのは非常に大変です。

そんなときに便利なのがシェルスクリプトです!

シェルスクリプトは複数のコマンドを一つのファイルにまとめて、基本的には上から順に実行していくものです。 ターミナル上での作業を自動化するのには必須のツールです。

このシェルスクリプト、個人で利用するにしても複数の人で利用するにしても、各行で何をしているのかなど可読性を高めておくのは非常に大切です。

というわけで、シェルスクリプトコメントアウトする方法をご紹介し、うっかりしていると嵌ってしまう落とし穴を回避する方法をご紹介したいと思います!

シェルスクリプトコメントアウトする方法

シェルスクリプトコメントアウトする方法は2通りあります。

  1. 一行だけコメントアウトする

  2. 複数行まとめてコメントアウトする

では、それぞれの方法を見ていきましょう!

一行のコメントアウト

一行のコメントアウトする方法は非常に簡単です!

その方法はコメントアウトしたい部分の先頭に#を付けるだけ

つまり、

#! /bin/bash

# これがコメントです

また、コマンドに続けてコメントを書くことも可能です

cp A B # コメント:AをBにコピーする

このように#を先頭に付けるだけでコメントアウトできますので、 コマンドのちょっとした意図や説明、さらには一行だけ処理をスキップしたい際には非常に便利です。

複数行のコメントアウト

続いて複数行のコメントアウトです!

複数行のコメントアウトも実は先程の#をまとめて先頭につけて行うこともできますが、一個一個#を付けていくのは非常に不便です。 ある種のエディタでは行頭に特定の文字を付加するような処理ができたりしますが、初心者にはなかなか難しいところです。

#を使うとこんな感じですね

#! /bin/bash

# ここが
# 複数行の
# コメントアウト

数行ぐらいならさくっとできてしまうかもしれませんが、処理の一ブロックをまとめてコメントアウトしたい場合といった大規模なコメントアウトには不便ですよね💦

そんな不便さを解決するのがヒアドキュメント<<

通常ヒアドキュメントといいますと、改行や空白などをそのまま標準入力としてコマンドに渡したりする際に使います。 使い方としては

cat << EOF
string1
string2
EOF

のようにすれば、

string1
string2

が出力されてます。改行がそのままcatに渡されていますね!

このようなヒアドキュメントをうまく使えばコメントアウトもできます!

#! /bin/bash

<< COMMENTOUT
ここをコメントアウトしたい1
ここをコメントアウトしたい2
ここをコメントアウトしたい3
COMMENTOUT

これで、複数行コメントアウトできちゃいます!

仕組みとしては、何もしないコマンドに対してCOMMENTOUTという文字列が入力されるまで標準入力として与え続けるというものになっています。

シェルスクリプトコメントアウトで気をつけるべきこと!

さて、ここまで

の2つの方法をご紹介しました!

これらは非常に便利なのですが、実はヒアドキュメントを使った複数行コメントアウトする方法には思わぬ罠が潜んでいますので、それについて書きたいと思います!

ヒアドキュメントを使った複数行コメントアウトの罠
問題

まずはどんな罠があるかをご紹介します。

次のようなシェルスクリプトを考えましょう。

#! /bin/bash

for f in *.txt
do
    {処理1}
    {処理2}
    {処理3}
done

これはカレントディレクトリの各txtファイルに対して処理1,処理2、処理3を順に施していくシェルスクリプトです。 ただし、各処理の前は空白4つをインデントとして入れています。

ここで処理2の部分だけコメントアウトしたいと思います。

#! /bin/bash

for f in *.txt
do
    {処理1}
    << COMMENTOUT
    {処理2}
    COMMENTOUT
    {処理3}
done

可読性のために、COMMENTOUTする部分に対しても、空白4つのインデントを入れてみました!

これで処理2の部分をコメントアウトできた!と思って実行してみると...

syntax error: unexpected end of file

おっと、なぜかEOFがいきなり来たというシンタックスエラー!

一体なぜでしょうか?

解説

この問題の仕組みは実は簡単です!

上でも書きましたようにヒアドキュメント内では空白や改行もそのまま解釈されます。

つまり、

#! /bin/bash

for f in *.txt
do
    {処理1}
    << COMMENTOUT
    {処理2}
    COMMENTOUT ##### この部分! #####
    {処理3}
done

で、COMMENTOUTの前の空白4個がそのまま読み込まれてしまって、ヒアドキュメント以降に"COMMENTOUT"という標準入力が来ないという問題が生じてしまっているからです。

まさかの可読性のために良かれと思って入れた空白4個のインデントが問題になってしまうとは...

実際に

#! /bin/bash

for f in *.txt
do
    {処理1}
    << COMMENTOUT
    {処理2}
COMMENTOUT
    {処理3}
done

のようにコメントアウトの終了部分のインデントとしての空白4個を消してみるとなんの問題もなく実行できます!

複数行コメントアウトの罠に陥らないために

さて、上ではヒアドキュメントを使って複数行コメントアウトする際に生じうる問題について書きました。

もちろん、ヒアドキュメントに詳しい人はそんな罠には嵌らないと思いますが、初めて触るという方にとってはなかなか気付きにくい落とし穴だと思います!

この罠を回避するための方針をお粗末ではありますが、いくつか列挙しておきます。

  1. そもそもヒアドキュメントを使ってコメントアウトをしない

    紹介しておいて何言ってんだという感じではありますが...上でも少し触れましたが複数行コメントアウトも一行コメントアウト#で実現できてしまいます。 ですので、行頭に#を差し込むような編集(Emacsならコメントアウトしたい範囲を選択してM-x replace-regexp→^→#かな)をすればこのような問題にはそもそもぶつりません。

  2. 先ほどの問題点の解説で示したようにコメントアウト終了の部分のインデントを無しにする

    確かにこれでも問題は解決します。(インデントを下げてる部分に少しだけ違和感のある行が出てくるのを許せる人に限りますが...)

  3. インデントをハードタブにして、ヒアドキュメントの<<<<-にする

適当に列挙してみましたが、こんなところでしょうか?

もっと方法があるとは思いますが、1.もしくは2.の方法が単純でいいのではないでしょうか?

まとめ

ということで、今回はシェルスクリプトコメントアウトする方法をご紹介しました。

一行でコメントアウトしたい場合は#コメントアウトしたい部分の先頭に複数行コメントアウトしたい場合はヒアドキュメントを使って

<< COMMENTOUT
コメントアウトしたい部分
COMMENTOUT

のようにすればOKです!

また、今回の記事ではヒアドキュメントを使ってコメントアウトした際にインデントの部分で思わぬエラーが発生する可能性があることについても触れました。 もちろんシェルに慣れていてヒアドキュメントに詳しい方なら陥らないとは思いますが、初めてヒアドキュメントに触れたという方にとっては気付きにくい問題です。

その問題を避けるための方針をいくつか挙げたのでぜひ参考にしていただければ幸いです。

ご意見やご質問、その他間違いのご指摘などございましたらぜひコメントのほどよろしくお願いします!