Help us understand the problem. What is going on with this article?

コメントアウトで問題解決をする

More than 3 years have passed since last update.

概要

コメントアウトを用いることで簡単に原因の特定をする方法を紹介いたします。
とても基礎的な内容ですが、自分で本当に理解できているのかどうか、この記事を書くことを通して確認したいと思います。

前提

chmodをした上で、bashのスクリプトvar.shを出力した時にエラーが出るので原因と特定してなんとかしたい。そのためにはコメントアウトが役に立つというお話。

そもそもコメントアウトって?

コードの行頭に一般的に#と書く事で「コードとしては一応書いてはあるが認識させないようにする技法」のことを指します。#かどうかはプログラミング言語によりますし、一度に複数行コメントアウトできる言語もあります。

例1:コメントアウトなしの場合

hello.sh

#!/bin/bash

echo "Hello world!"
$ bash hello.sh
Hello world!

例2:コメントアウトありの場合

echoの前に#を足してみます。
hide_hello.sh

#!/bin/bash

#echo "Hello world!"
$ bash hide_hello.sh
$

何も表示されません。以上のことを表にまとめてみます。

コード 出力結果
hello.sh echo "Hello world!" Hello world!
hide_hello.sh #echo "Hello world!" (何も表示されない)

つまり、「コードとしては(一応)存在はしているが、認識されなくなる」というのがコメントアウト(#)の役割です。

コメントアウトを問題解決に用いる

以下のようなコードを書いたがエラーが出たが、どこに原因があるのかがわからない場合を想定し、それに対してコメントアウトを用いて問題解決をします。

例1:このサンプルコードを使っていきます

var.sh

#!/bin/bash

#A
function datetime() {
    #A-1
    DATE=`date '+%Y-%m-%d'`
    TIME=`date '+%H:%M:%S'`

    #A-2
    echo ${DATE}${TIME}
    echo DATETIME
    echo $DATETIME
}

#B
datetime()
$ bash var.sh
var.sh: line 17: syntax error: unexpected end of file

エラーになってしまいました。コードを要素にバラして表にします。
以下、コメントアウトしていない箇所を「表示」、コメントアウトした箇所を「非表示」とします。

A-1 A-2 B 出力結果
例1 表示 表示 表示 error

じゃあこの問題をどう解決するのか。タイトル通り、コメントアウト(#)を使います。

「コードとしては(一応)存在はしているが、認識されなくなる」というのがコメントアウトの特徴なので、その特徴を活かして原因の特定に役立つことを見ていきます。

例2:全部コメントアウトしてみる

例1を一度すべてコメントアウトをしてここに原因があることを確認してみます。

#!/bin/bash

# すべての要素をコメントアウトした
##A
#function datetime() {
#    #A-1
#    DATE=`date '+%Y-%m-%d'`
#    TIME=`date '+%H:%M:%S'`
#
#    #A-2
#    echo ${DATE}${TIME}
#    echo DATETIME
#    echo $DATETIME
#}
#
##B
#datetime()
$ bash var.sh
$

何もエラーが出ませんでした。表に追加して意味を読み取ります。

A-1 A-2 B 出力結果
例1 表示 表示 表示 error
例2 非表示 非表示 非表示 errorなし

例1と例2から、このファイルのなんらかの記述が原因でエラーを吐いていることが確認できます。(当然ですが)
この作業を構造的に繰り返していくとエラーの特定ができることをみていきます。

例3:1/3コメントアウトしてみる(その1)

A-1だけコメントアウトしてみます。

コード

#!/bin/bash

#A
function datetime() {
    ##A-1 A-1だけコメントアウトした
    #DATE=`date '+%Y-%m-%d'`
    #TIME=`date '+%H:%M:%S'`

    #A-2
    echo ${DATE}${TIME}
    echo DATETIME
    echo $DATETIME
}

#B
datetime()

出力結果

$ bash var.sh
var.sh: line 17: syntax error: unexpected end of file

エラーでした。表に追加して意味を読み取ります。

A-1 A-2 B 出力結果
例1 表示 表示 表示 error
例2 非表示 非表示 非表示 errorなし
例3 非表示 表示 表示 error

例1~3から、A-2とBが表示されているならばerrorのようです。では、じゃあA-2かBが原因っぽいですね。

次はA-2だけをコメントアウトしてみます。

例4:1/3コメントアウトしてみる(その2)

A-2をコメントアウトします。

#!/bin/bash

#A
function datetime() {
    #A-1
    DATE=`date '+%Y-%m-%d'`
    TIME=`date '+%H:%M:%S'`

    ##A-2 次はここだけをコメントアウトしました
    #echo ${DATE}${TIME}
    #echo DATETIME
    #echo $DATETIME
}

#B
datetime()
$ bash var.sh
var.sh: line 17: syntax error: unexpected end of file

エラーが出ました。表に追加して意味を読み取ります。

A-1 A-2 B 出力結果
例1 表示 表示 表示 error
例2 非表示 非表示 非表示 errorなし
例3 非表示 表示 表示 error
例4 表示 非表示 表示 error

このファイルが要素A-1とA-2とBで構成されていて、その上でエラーが出ています。また、例2~4から、A-1とA-2がerrorの原因でないということがわかります。ということは...??

例5:1/3コメントアウトしてみる(その3)

Bをコメントアウトします。

#!/bin/bash

#A
function datetime() {
    #A-1
    DATE=`date '+%Y-%m-%d'`
    TIME=`date '+%H:%M:%S'`

    ##A-2
    echo ${DATE}${TIME}
    echo DATETIME
    echo $DATETIME
}

#B ここをコメントアウトした
#datetime()
$ bash var.sh
$ 

おお。エラーがなくなりました。表に追加します。

A-1 A-2 B 出力結果
例1 表示 表示 表示 error
例2 非表示 非表示 非表示 errorなし
例3 非表示 表示 表示 error
例4 表示 非表示 表示 error
例5 表示 表示 非表示 errorなし

この表の意味を読み取ります。
要素Bが表示されている → 出力結果がerror
要素Bが表示されていない → 出力結果がerrorなし

という関係が見られました。なので、このerrorはBが怪しいようです。

あとは怪しいであろうdatetime()を要素に分解して、同じように調べていくだけです。
ちなみに、この例のdatetime()ではぱっと見で原因が掴めるので分解する必要性は高くないのですが、見慣れないメソッドなどの場合、以下のようにバラバラにしていきます。

bashスクリプトのfunctionの呼び出しは、

関数呼び出し = 呼び出す関数名 + 引数部分

という構成になっています。なので、datetime()を関数datetimeと引数部
分()にさらに分解して、同じようにコメントアウトで比較していきます。(例は省略します)

datetime () 結果
例1 非表示 非表示 errorなし
例2 表示 表示 error
例3 表示 非表示 errorなし
例4 非表示 表示 error

この表の意味を読み取ります。

例2から「関数datetimeを表示し、かつ、引数()を表示」ならばerror
例3から「関数datetimeを表示し、かつ、引数()を非表示」ならばerrorなし

という関係が見られました。つまり、datetime関数呼び出しの際の引数()が悪さをしていたんですね。
datetime関数呼び出しの際の引数()をコメントアウトをしてみます。

例6:原因をピンポイントでコメントアウトしてみる

#!/bin/bash

#A
function datetime() {
    #A-1
    DATE=`date '+%Y-%m-%d'`
    TIME=`date '+%H:%M:%S'`

    #A-2
    echo ${DATE}${TIME}
    echo DATETIME
    echo $DATETIME
}

#B
#datetime関数の後の()をコメントアウトした。
datetime #()
$ bash var.sh
2016-12-1821:54:00
DATETIME

$

エラーが解決しました。
以上より、var.shのエラーの原因は要素Bの関数datetimeを呼び出す際に余分な引数である()が指定されていることであるとわかりました。コメントアウトを構造的に行っていくと簡単に問題解決できるよ、というお話でした。

非常に拙い内容ですが、最後まで見ていただきありがとうございました。

ytksy
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away