質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.35%

  • bash

    870questions

    bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。

bashコマンドの読解

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,120

amaguri

score 217

bashで書かれていたコードを読解していたのですがわからないことがたくさんあったので質問させていただきます。
bashは触ったことがないので全くの初心者になります。
今回わからないことは
・LST_DATABASE="$BASE_DIR/database.lst"と宣言していきなり、echo "[$LST_DATABASE]"で宣言していない$LST_DATABASEが出てくること。
これはLST_DATABASE=$LST_DATABASEなのか?

・hive -S -v -f $変数A > $変数B の処理 -vはなんでしょうか?調べてもでてきません。
hive -S -f $変数A > $変数B はサイレントモードで$変数ファイルAを$変数Bに出力だと思いますが。。。

・if [ "$tblname" != "" ];then の動き
これは"$tblname"の!= が空白の時ということですか?
これも意味がよくわかりません。
"$tblname"=""ならわかるのですが。。。

・cp /dev/null $変数 の処理
cpはコピーするということで/dev/nullのパスを$変数にコピーするということでしょうか?

・tblname=echo $line | awk '{print $3}'の処理
$line書き出しをawk {print $3}を利用して入力ファイルの各行の 3番目のフィールドが出力される処理に出力するというのはつまりどういうことになるのでしょうか?

下記がコードと読解したメモになります。

. /opt/mapr/mapr_bashrc

BASE_DIR="/var/www/html/WebHive/entity/data"     //BASE_DIR=ログファイルのある場所のパス

#データベース一覧情報
LST_DATABASE="$BASE_DIR/database.lst"
echo "[$LST_DATABASE]"                            //$LST_DATABASEの書き出し
hive -S -e "show databases;" > $LST_DATABASE    //$LST_DATABASEに対してshow databases;を実行で取得したデータを$LST_DATABASEに出力。    //余計なMsgを出力させたくない時はサイレントモード-Sを利用する。-eオプションで通常のコマンドからクエリを実行することが可能。>=リダイレクト

while read dbname                                //DBの名前を読み込む。        while 文は「ある条件が成り立っている間のみ繰り返し処理を実行する」といった、不定回の繰り返し処理を行う場合に使用するループ制御文である。
do                                                //ループ開始
    #ディレクトリ作成
    if [ ! -d "$BASE_DIR/$dbname" ];then        //if文開始    ディレクトリが"$BASE_DIR/$dbname"ではない場合 thenif文で必要な宣言。 //-d=ディレクトリ。
        mkdir $BASE_DIR/$dbname                    //$BASE_DIR/$dbnameでディレクトリを作る。
    fi                                             //if文終了

    if [ ! -d "$BASE_DIR/$dbname/table" ];then    //ディレクトリが"$BASE_DIR/$dbname/table"ではない場合
        mkdir $BASE_DIR/$dbname/table             //$BASE_DIR/$dbname/tableでディレクトリを作る。
    fi

    if [ ! -d "$BASE_DIR/$dbname/partition" ];then     //if文開始    ディレクトリが"$BASE_DIR/$dbname/partition"ではない場合
        mkdir $BASE_DIR/$dbname/partition            //$BASE_DIR/$dbname/partitionでディレクトリを作る
    fi

    #テーブル一覧
    LST_TABLE="$BASE_DIR/$dbname/table.lst"
    echo "[$LST_TABLE]"                                        //$LST_TABLEの書き出し
    hive -S -e "use $dbname;show tables;" > $LST_TABLE        //ディレクトリを作った$dbnameに対してshow tables;を実行で取得したデータを$LST_TABLE出力。

    #テーブル情報取得
    TBL_HQL_FILE="$BASE_DIR/$dbname/table.hql"
    TBL_TMP_FILE="$BASE_DIR/$dbname/table.tmp"
    echo "[$TBL_HQL_FILE]"                                    //$TBL_HQL_FILEの書き出し
    echo "use $dbname;" > $TBL_HQL_FILE                     //use $dbname;の書き出しを$TBL_HQL_FILEに出力

    while read tblname                                         //テーブルの名前を読み込む
    do
        echo "desc formatted ${tblname};" >> $TBL_HQL_FILE     //${tblname}のテーブルの情報の表示結果を$TBL_HQL_FILEに追加上書き    //テーブルの情報を表示する。DESCRIBEは省略して「DESC」を使用可能。formattedを付けると、詳細情報が整形された分かりやすい状態で表示される。>>=ファイルに追加書き込みした場合は>>を使う。
    done < $LST_TABLE                                         //done$LST_TABLEを出力。 done=ループ終了。

    hive -S -v -f $TBL_HQL_FILE > $TBL_TMP_FILE             /-vが何か不明。おそらく$TBL_HQL_FILEをサイレントオプショんとなんらかのオプションの実行結果を$TBL_TMP_FILEに出力        //-fでクエリを記述したファイルを読み込ませて実行 //-f=ファイル
    #テーブル情報個別ファイル出力
    LST_DESC=""
    while read line                                                    //ラインの読み込み
    do
        if [ "`echo $line | grep '^desc formatted'`" != "" ];then     //よく意味がわからない。$lineの書き出だし|^desc formattedから始まる行の探し出し。!=空白の場合                                            //grep=ファイルや標準入力から正規表現でマッチする行を探し出すコマンド
            tblname=`echo $line | awk '{print $3}'`                 //awkがイマイチ理解できていない。tblname=$lineの書き出し。awk {print $3}を利用して入力ファイルの各行の 3番目のフィールドが出力する。
            if [ "$tblname" != "" ];then                             //よく意味がわからない。$tblname !=空欄の場合?。
                LST_DESC="$BASE_DIR/$dbname/table/${tblname}.dat"
                echo "[$LST_DESC]"                                     //$LST_DESCの書き出し。
                cp /dev/null $LST_DESC                                 //よく意味がわからない。/dev/nullというパス?を$LST_DESCという変数でコピー?                //cp=おそらくファイルコピーのコマンド
            fi
            continue                                                 //continueによって次の繰り返しに飛ぶ.
        fi
        if [ "$LST_DESC" == "" ];then                                 //$LST_DESC=空白の時。
            continue
        fi
        echo $line >> $LST_DESC                                        //$lineの書き出しデータを$LST_DESCに追加上書き。
    done < $TBL_TMP_FILE                                             // done$TBL_TMP_FILEの結果を出力。

    #パーティション情報取得
    PRT_HQL_FILE="$BASE_DIR/$dbname/partition.hql"
    PRT_TMP_FILE="$BASE_DIR/$dbname/partition.tmp"
    echo "[$PRT_HQL_FILE]"                                                        //$PRT_HQL_FILEの書き出し
    echo "use $dbname;" > $PRT_HQL_FILE                                         //use $dbname;の書き出しを$PRT_HQL_FILEに出力
    tblname=""
    while read line
    do
        if [ "`echo $line | grep '^desc formatted'`" != "" ];then                //$lineの書き出だしをdesc formattedから始まる行の探し出し。!=空白の場合の処理に出力 //|=パイプ:あるプロセスの実行結果を別のプロセスの入力にリダイレクトすることもできる.
            tblname=`echo $line | awk '{print $3}'`                                //awkがイマイチ理解できていない。tblname=$lineの書き出し。awk {print $3}を利用して入力ファイルの各行の 3番目のフィールドが出力する。
            continue
        fi
        if [ "$tblname" == "" ];then                                             //$tblname !=空欄の場合。
            continue
        fi
        if [ "`echo $line | grep '^# Partition Information'`" != "" ];then         //$lineの書き出だしをPartition Informationから始まる行の探し出し。!=空白の場合の処理に出力
            echo "show partitions $tblname;" >> $PRT_HQL_FILE                     //show partitions $tblname;の書き出しを$PRT_HQL_FILEに追加上書き
            tblname=""
            continue
        fi
    done < $TBL_TMP_FILE                                                         //done$TBL_TMP_FILEを出力
    hive -S -v -f $PRT_HQL_FILE > $PRT_TMP_FILE                                 //-vが何か不明。おそらく$PRT_HQL_FILEをサイレントオプショんとなんらかのオプションでの実行結果を$TBL_TMP_FILEに出力

    #パーティション情報個別ファイル出力
    LST_PART=""
    while read line
    do
        if [ "`echo $line | grep '^show partitions'`" != "" ];then                 //$lineの書き出だしをshow partitions!=空白の場合の処理に出力
            tblname=`echo $line | awk '{print $3}'`                             //awkがイマイチ理解できていない。tblname=$lineの書き出し。awk {print $3}を利用して入力ファイルの各行の 3番目のフィールドが出力する。
            if [ "$tblname" != "" ];then                                         //よく意味がわからない。$tblname !=空欄の場合?。
                LST_PART="$BASE_DIR/$dbname/partition/${tblname}.dat"
                echo "[$LST_PART]"                                                 //$LST_PARTの書き出し
                cp /dev/null $LST_PART                                             //よく意味がわからない。/dev/nullというパス?を$LST_DESCという変数でコピー?
            fi
            continue
        fi
        if [ "$LST_PART" == "" ];then
            continue
        fi
        echo $line >> $LST_PART                                                 //$lineの書き出しを$LST_PARTに追加上書き
    done < $PRT_TMP_FILE                                                         //done$PRT_TMP_FILEを出力

done < $LST_DATABASE                                                            //done$LST_DATABASEを出力

exit 0
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • kunai

    2016/10/03 14:58

    流石に0から全部というのはアレですので。。最低限、シェルスクリプトの基本的な文法くらいは調べたり学んだりしてから、その上でわからない事があればご質問いただくのはいかがでしょうか。

    キャンセル

  • amaguri

    2016/10/03 15:13

    わからないところなどは調べた上で-vの処理など調べ方もあると思いますが自分で調べてもわからないとこを質問させていただいたのですがどのクオリティまで行かなければ質問してはいけないでしょうか?今回確かにいきなりの読解になってしまい調べながら読解したつもりではあったので

    キャンセル

  • Yoshikatsu_

    2016/10/03 15:18

    パイプ、リダイレクトの理解は必要でしょう。検索してみて下さい。

    キャンセル

  • amaguri

    2016/10/03 15:22

    Yoshikatsuさんパイプ、リダイレクトですねありがとうございます。
    なんと調べて良かったのかわからずじまいでしたのでとても助かりました

    キャンセル

回答 4

+2

「わからないところを調べる」のではなく、「bash の基本について一通り学ぶ」ところから始めるのが良いと思います。「bash 入門」などで検索すれば山ほど資料が出てくると思います。
質問しては行けないということはないですが、それくらい初歩的な内容の質問で、これに答えていると回答者はすでに世にたくさんある入門記事を新しく作ることになってしまいます。
新しい言語を学ぶわけですから、時間はかかると思いますが、結果を急がず1つずつ積み重ねて行くのが良いかと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/10/03 17:52

    回答ありがとうございます。今回bashで書かれていたこのコードをphpに書く変えるために処理の内容を把握したかったので質問させていただきました。結果を急がず1つずつ積み重ねていけるように努力します。

    キャンセル

checkベストアンサー

0

今回わからないことは 
・LST_DATABASE="$BASE_DIR/database.lst"と宣言していきなり、echo "[$LST_DATABASE]"で宣言していない$LST_DATABASEが出てくること。 
これはLST_DATABASE=$LST_DATABASEなのか?

シェル変数は代入の時は$が不要で参照の際は$を付けます。
echo "[echo "[$LST_DATABASE]"]"は、echo "[$LST_DATABASE]"先に$LST_DATABASE
が設定内容に置き換わった後でechoが実行されます。[ ]はでーたの両端を括って見やすくした
と思われます。

・hive -S -v -f $変数A > $変数B の処理 -vはなんでしょうか?調べてもでてきません。 
hive -S -f $変数A > $変数B はサイレントモードで$変数ファイルAを$変数Bに出力だと思いますが。。。

hiveコマンドを実行する際の-fオプションに$変数Aを指定していて 実行時のイメージは下記の様に
なります
hive -S -f ファイルA > ファイルB
-Sはサイレントモード
-fはコマンドファイル(クエリ)読込み
>の意味はリダイレクション、これが無い場合は出力が画面に表示されるので、その出力先をファイルに
変更すると言う意味になります。書込みです。
>>は追加書込みの意味でファイルの最終行に加える事になります。
-vは実行SQL文を出力する様です(指定しないと結果だけ?)

if [ "$tblname" != "" ];then の動き 
これは"$tblname"の!= が空白の時ということですか? 
これも意味がよくわかりません。
"$tblname"=""ならわかるのですが。。。 

!=はnotイコールなので空白でない場合になります。
[ ! "$tblname" == "" ]でも同じです。イコールは一つでも良いですが2個が推奨らしいです。

・cp /dev/null $変数 の処理 
cpはコピーするということで/dev/nullのパスを$変数にコピーするということでしょうか?

cp /dev/null $変数 は空の$変数ファイルを作成するまたはファイルを空にすると言う事です

・tblname=echo $line | awk '{print $3}'の処理 
$line書き出しをawk {print $3}を利用して入力ファイルの各行の 3番目のフィールドが出力される処理に出力するというのはつまりどういうことになるのでしょうか?

次の行あたりから推測するとPRT_TMP_FILEのファイルにはテーブル名が3番目に存在していて、
その他の行は2フィールド以内と思われる。テーブル名が見つかるとファイル名をLST_PARTに
設定してその中にlineデータを書き込む(アペンド)複数行可能

最終的に$BASE_DIR/$dbname/partition/${tblname}.datと言うファイルが作成される。
${tblname}=$tblname 同じであるが、上記では問題ないが変数の括りでBASHが誤解しない
様に明示的に指定しています。

余計なお世話かもしてませんが他の不明項目も追加します。

. /opt/mapr/mapr_bashrc

外部ファイルを取込実行します。環境変数やfunction等が定義されています。

if [ "echo $line | grep '^desc formatted'" != "" ];then

読み込まれた行の先頭が'desc formatted’で始まる行$lineであれば出力が行われ”echo ...
に値が入るます すると!=""条件がtureとなりthen以降が実行されます。

tblname=echo $line | awk '{print $3}'

$lineにはフィールドセパレータが空白かタブで文字列が作成されていて、これをawkは$1、$2、$3として
フィールド処理が行えます。セパレータは-Fにて指定できます。

シェルはファイルハンドリングが得意なのでコマンドでデータを抽出してファイルに書き出し、これをまた読込み処理を行う形態で作成されていると思われます。phpでのシェルコマンド実行結果は、ファイルよりも、配列に格納して同様な処理を行うのも良いと思います。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/10/03 18:08

    一つ一つをとても細かく説明していただきありがとうございます。
    とてもわかりやすく読みやすかったです。
    一番早く回答していただきましたのでBAにさせて頂きます。

    キャンセル

0

変数に代入するときは$無し 変数の値を参照するときは$をつけます

hiveコマンドはRDBのマニュアルを調べてみて下さい、私は使ったことがありません。

・if [ "$tblname" != "" ];then の動き
は変数$tblnameに何か文字列が入っていたら以下の処理を行うですね

while read 変数B
do 
.
.
.
done < $変数A
の構文で$変数Aのファイルの各行がwhileをループする毎に変数Bに設定されファイルのEOFまでループ内が処理されます。

・cp /dev/null $変数 の処理 
$変数にnullが設定されクリアされます。

・tblname=echo $line | awk '{print $3}'の処理 
$line変数の3番めのフィールドの値を変数tblnameに代入です

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/10/03 17:57

    回答ありがとうございます。
    わかりやすく説明していただきとても助かりました!

    キャンセル

0

・LST_DATABASE="$BASE_DIR/database.lst"と宣言していきなり、echo "[$LST_DATABASE]"で宣言していない$LST_DATABASEが出てくること。 
これはLST_DATABASE=$LST_DATABASEなのか?

シェル変数に何かの値を代入するときには$がつかなくて、シェル変数を評価するときには$がつきます。

BASE_DIR="/var/www/html/WebHive/entity/data"

と書かれていたら、シェル変数BASE_DIRの中には"/var/www/html/WebHive/entity/data"
という文字列が代入された、ということです。

次の行で
LST_DATABASE="$BASE_DIR/database.lst"
となっていますね。
これはシェル変数LST_DATABASEにシェル変数BASE_DIRの中身と/database.lstという文字列をつなげたもの
が代入される、ということになります。
つまりLST_DATABASEの中身は"/var/www/html/WebHive/entity/data/database.lst"
という文字列になります。

・hive -S -v -f $変数A > $変数B の処理 -vはなんでしょうか?調べてもでてきません。 
hive -S -f $変数A > $変数B はサイレントモードで$変数ファイルAを$変数Bに出力だと思いますが。。。

hiveのvオプション、調べてもなかなか出てきませんね。

hive --help

で英語のヘルプが出てきませんか?

usage: hive
 -d,--define <key=value>          Variable subsitution to apply to hive
                                  commands. e.g. -d A=B or --define A=B
 -e <quoted-query-string>         SQL from command line
 -f <filename>                    SQL from files
 -H,--help                        Print help information
 -h <hostname>                    Connecting to Hive Server on remote host
    --hiveconf <property=value>   Use value for given property
    --hivevar <key=value>         Variable subsitution to apply to hive
                                  commands. e.g. --hivevar A=B
 -i <filename>                    Initialization SQL file
 -p <port>                        Connecting to Hive Server on port number
 -S,--silent                      Silent mode in interactive shell
 -v,--verbose                     Verbose mode (echo executed SQL to the
                                  console)


ということで-vは冗長モード(実行したSQL文をコンソール画面に出す)ということのようですね。

>・if [ "$tblname" != "" ];then の動き 
これは"$tblname"の!= が空白の時ということですか? 
これも意味がよくわかりません。 
"$tblname"=""ならわかるのですが。。。 

!=は「イコールではない」です。
つまり、シェル変数tblnameが空でないならば、という意味になります。

・cp /dev/null $変数 の処理 
cpはコピーするということで/dev/nullのパスを$変数にコピーするということでしょうか?

/dev/nullはUnix/Linuxではちょっと特殊なファイルです。
cp /dev/null ファイル名
とすると、ファイル名で示されるファイルの中身が0バイト(空)になります。

・tblname=echo $line | awk '{print $3}'の処理 
$line書き出しをawk {print $3}を利用して入力ファイルの各行の 3番目のフィールドが出力される処理に出力するというのはつまりどういうことになるのでしょうか?

そこに行く前に、このシェルスクリプトでよく使われている構造をちょっとおさらい。

10行目    hive -S -e "show databases;" > $LST_DATABASE
12行目    while read dbname 
13行目    do

~ここからなんだかいろんな処理がたくさん~

105行目    done < $LST_DATABASE

となっているのがこのシェルスクリプトのメインループです。

何をやっているのかというと、
10行目の hive -S -e "show databases;" > $LST_DATABASE
でデータベースの一覧を$LST_DATABASEで示されるファイルに書き込んでいます。

で、12行目でreadというコマンドを実行していますが、readは標準入力から1行読み込む、という意味です。
通常でしたらターミナルから読むわけですが、105行目で、< $LST_DATABASEとなっているので、これは、

hiveコマンドで取得したデータベース一覧のファイルを1行ずつ読み込んで処理する

という流れになります。

上記を踏まえて、91行目の

tblname=`echo $line | awk '{print $3}'`


を見ると、$lineは、その前の88行目のreadコマンドで読み込まれていますね。
103行目で標準入力をターミナルから$PRT_TMP_FILEに変更しています。

じゃあその$PRT_TMP_FILEってどうやって作られているかというと、
84行目の hive -S -v -f $PRT_HQL_FILE > $PRT_TMP_FILEで作成されています。
このファイルから一行読み込んだ内容が$lineになります。

これがどんなデータなのかはちょっとわかりません。

echo $line

でその$lineの内容を出力しているのですが、その出力を次のawkコマンドの入力につなげるのがパイプ"|"です。

awk '{print $3}'とすると、awkは一行読み込んで3カラム目を出力します。

このecho $line | awk '{print $3}'という行がバッククオート"`"でくくられていることに注意してください。

これはecho $line |  awk '{print $3}'の出力結果をシェル変数tblnameに代入している、という意味です。

最後に。
シェルスクリプトは"//"以降をコメントとみなし「ません」。
コメントは"#"を使ってください。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/10/03 18:08

    一つ一つをとても細かく説明していただきありがとうございます。
    とてもわかりやすく読みやすかったです。
    シェルスクリプトでは"#"を使うようにさせていただきます!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.35%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • bash

    870questions

    bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。