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

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

新規登録して質問してみよう
ただいま回答率
85.49%
bash

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

Q&A

解決済

4回答

2835閲覧

bashコマンドの読解

amaguri

総合スコア227

bash

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

0グッド

0クリップ

投稿2016/10/03 05:55

編集2016/10/03 07:14

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"ではない場合 then=if文で必要な宣言。 //-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

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kunai

2016/10/03 05:58

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

2016/10/03 06:13

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

2016/10/03 06:18

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

2016/10/03 06:22

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

回答4

0

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

投稿2016/10/03 07:55

thinca

総合スコア1864

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

amaguri

2016/10/03 08:52

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

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 08:32

編集2016/10/03 10:34
A.Ichi

総合スコア4070

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

amaguri

2016/10/03 09:08

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

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 07:56

編集2016/10/03 07:59
imutakaoru

総合スコア356

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

amaguri

2016/10/03 09:08

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

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 07:52

Yoshikatsu_

総合スコア47

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

amaguri

2016/10/03 08:57

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問