【予期せぬシンタックスエラー!?】Shell Scriptでコメントアウトする方法!
ちょこっとした作業の際に便利なShell Script。
ファイルの一括操作や面倒な処理の自動化などいろんな用途で活用することができます!
ですが、このシェルスクリプト、コメントアウトする際に気をつけてないと思わぬ罠に嵌ってしまうことがあります💦
ということで、今回の記事ではシェルスクリプトにおいて複数行コメントアウトする方法とその際に気を付けることの二点をお伝えします!
はじめに
ターミナル上で作業するのに欠かせない各種コマンド。 LinuxやMacなどで欠かせません。
ですが、コマンドを一個一個対話的に打っていくのは非常に大変です。
そんなときに便利なのがシェルスクリプトです!
シェルスクリプトは複数のコマンドを一つのファイルにまとめて、基本的には上から順に実行していくものです。 ターミナル上での作業を自動化するのには必須のツールです。
このシェルスクリプト、個人で利用するにしても複数の人で利用するにしても、各行で何をしているのかなど可読性を高めておくのは非常に大切です。
というわけで、シェルスクリプトでコメントアウトする方法をご紹介し、うっかりしていると嵌ってしまう落とし穴を回避する方法をご紹介したいと思います!
シェルスクリプトでコメントアウトする方法
では、それぞれの方法を見ていきましょう!
一行のコメントアウト
一行のコメントアウトする方法は非常に簡単です!
その方法はコメントアウトしたい部分の先頭に#
を付けるだけ。
つまり、
#! /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個を消してみるとなんの問題もなく実行できます!
複数行コメントアウトの罠に陥らないために
さて、上ではヒアドキュメントを使って複数行コメントアウトする際に生じうる問題について書きました。
もちろん、ヒアドキュメントに詳しい人はそんな罠には嵌らないと思いますが、初めて触るという方にとってはなかなか気付きにくい落とし穴だと思います!
この罠を回避するための方針をお粗末ではありますが、いくつか列挙しておきます。
そもそもヒアドキュメントを使ってコメントアウトをしない
紹介しておいて何言ってんだという感じではありますが...上でも少し触れましたが複数行コメントアウトも一行コメントアウトの
#
で実現できてしまいます。 ですので、行頭に#
を差し込むような編集(Emacsならコメントアウトしたい範囲を選択してM-x replace-regexp→^→#かな)をすればこのような問題にはそもそもぶつりません。先ほどの問題点の解説で示したようにコメントアウト終了の部分のインデントを無しにする
確かにこれでも問題は解決します。(インデントを下げてる部分に少しだけ違和感のある行が出てくるのを許せる人に限りますが...)
インデントをハードタブにして、ヒアドキュメントの
<<
を<<-
にする
適当に列挙してみましたが、こんなところでしょうか?
もっと方法があるとは思いますが、1.もしくは2.の方法が単純でいいのではないでしょうか?
まとめ
ということで、今回はシェルスクリプトでコメントアウトする方法をご紹介しました。
一行でコメントアウトしたい場合は#
をコメントアウトしたい部分の先頭に、複数行コメントアウトしたい場合はヒアドキュメントを使って
<< COMMENTOUT コメントアウトしたい部分 COMMENTOUT
のようにすればOKです!
また、今回の記事ではヒアドキュメントを使ってコメントアウトした際にインデントの部分で思わぬエラーが発生する可能性があることについても触れました。 もちろんシェルに慣れていてヒアドキュメントに詳しい方なら陥らないとは思いますが、初めてヒアドキュメントに触れたという方にとっては気付きにくい問題です。
その問題を避けるための方針をいくつか挙げたのでぜひ参考にしていただければ幸いです。
ご意見やご質問、その他間違いのご指摘などございましたらぜひコメントのほどよろしくお願いします!