Lubuntu 初めてのシェルスクリプト

前回の記事に基づき、youtube閲覧中に気になる音源があればすぐにURLリストに登録できるスクリプトの作成を行います。

その前に、一番簡単なシェルスクリプトを作成して、動作確認を行います。

#!/bin/sh

echo “Hello,World!!”

以上の簡単なスクリプトをhelloworld.shとしてカレントディレクトリに作成

$ chmod u+x helloworld.sh

として実行権限を与えます

$ helloworld.shと打っても動作しません

$ helloworld.sh
helloworld.sh: コマンドが見つかりません

 

原因は、パスが通っていない=環境変数 $PATHにホームディレクトリが含まれていないからでした。そこで、

$ ./helloworld.sh
Hello,World!!

上記のように明示的にパスを指定してあげると動作しました。

 

それでは、まず処理の簡単な仕様を作成します。

#コマンド名 addmurl
#(引数の個数は1とする。)
#引数が1個の場合
#URLのアクセスチェック
#チェックOKの場合
#URLの重複チェックを行う
#URLに重複がない場合
#URLをmusic_dl_listに追記する。
#URLに重複がある場合
#メッセージ***このURLはすでに登録されています。***を表示して終了
#チェックNGの場合
#メッセージ**引数に有効なURLを指定してください**を表示して終了
#引数が1個以外の場合
#メッセージ**URLを1つだけ指定してください。**を表示して終了

 

仕様は以上のような簡単なものです。

上記のシェルスクリプト作成にあたって必要なのは、条件分岐です。ifを用います。他に、URLのアクセスチェックを行うためにwgetを使用します。また、if文の条件にtestコマンドを用います。加えて、特殊変数を用いてパラメータの情報を使用します。

if文

条件分岐で一番ポピュラーなのが、他言語でも多く用いられるif文です。

基本になるのが以下のような構文です。

if 条件式1 ; then
処理1
else
処理2
fi

条件判断が複数になる場合以下のような構文が用いられます

if 条件式1 ; then
処理1
elif 条件式2 ; then
処理2
else
処理3
fi

if文の条件式の部分は実際は、testコマンドで記されます。

testコマンド

構文は

数値の比較の場合

test 数値1(式) 比較演算子 数値2(式)

というような形式で使われます。

比較演算子は次のようなものが使われます。

-eq → equal(= と同等)
-ne → not equal(!= と同等)
-lt → less than (< と同等)
-le → less than or equal(<= と同等)
-gt → greater than(> と同等)
-ge → greater than or equal(>= と同等)

文字列の比較の場合

test 文字列 比較演算子 文字列

比較演算子は次のようなものが使われます。

文字列1 = 文字列2 (文字列1と文字列2が同じならば真)
文字列1 == 文字列2 (文字列1と文字列2が同じならば真(上と同じ))
文字列1 != 文字列2 (文字列1と文字列2が異なれば真)

使用例 test hoge -lt 1 (hogeが1より小さい時)

testが単独で使用される場合結果は、条件が成り立つ場合に真(0)成り立たない場合は偽(1)を返します。真(0) か偽(1) かの終了ステータスを返すのみで、画面上へのメッセージ出力等は一切行われません。終了ステータスは、特殊変数 $? で確認できます。

testコマンドには、これ以外にもたくさん機能があるので別途研究します。

wgetコマンド(ファイルをFTPサーバーやWebサーバーからダウンロードする。)

通常、ファイルのダウンロードに用いますが、今回は、アクセスチェックに用います。

オプションとして以下のものを用います。

–spider ファイルをダウンロードしない。

-nv 冗長メッセージを出力せず、エラーメッセージと基本情報のみを出力。

-t 接続拒否や 404 が返ってきたときに再試行する回数。デフォルトは 20回。

特殊変数

シェルスクリプトに引数を与えたい時があります。そんな時に、引数を参照できる特殊変数というものがあります。

特殊変数は以下のものが使用可能です

特殊変数 意味
$0 シェルスクリプトの名前
$n n番目の引数
$* すべての引数リスト
$# 与えられた引数の数
$? 直前に実行したコマンドの戻り値
$$ シェルスクリプトが実行された際のPID
$LINENO この変数を記述した行番号

上記以外にも特殊変数には使い方があるので別途研究します。

以下以上の内容を使って作成したシェルスクリプトです。

#!/bin/bash
######################################
#addmurl (add url to music_url_list) #コマンド名 addmurl
######################################
if test $# -eq 1;then #引数が1個の場合
# URLのアクセスチェック
urlcheck=$( wget –spider -nv -t 1 $1 2>&1 | grep -c ‘200 OK’ )
if test $urlcheck -eq 1;then
# urlチェックの値が1の時、URLの重複チェックを行う
dupcnt=$( cat music_url_list | grep -c $1 )
if test $dupcnt -eq 0;then
# URLに重複がない場合
# music_url_listにurlを追記する。
echo $1 >>music_url_list
else
# URLに重複がある場合
#メッセージ***このURLはすでに登録されています。***を表示して終了
echo “このURLはすでに登録されています。”
fi
else
echo “正しいurlを指定してください。”   #チェックNGの場合
fi
else
echo “URLを1つだけ指定してください。”  #引数が1個以外の場合
fi

上記のように作成実行しましたが、

$ ./addmurl https://www.youtube.com/watch?v=3fF_XqQDkI
./addmurl: 行 26: 構文エラー: 予期しないファイル終了 (EOF) です

とエラーメッセージが表示されました。
ググっているとどうも改行コードに不正なものが含まれているようです。
原因として考えられるのは、コード作成に自宅のubuntuと職場のCygwinを併用していたことにありそうです。

どうやって確認するかをググっているとodコマンドを使うと、確認できるのを発見しました。

$ od -c ./addmurl

で実行

0000000 # ! / b i n / b a s h \n # # # #
0000020 # # # # # # # # # # # # # # # #
*
0000060 # # \n # a d d m u r l ( a d d
0000100 u r l t o m u s i c _ u r
0000120 l _ l i s t ) # 343 202 263 343 203 236
0000140 343 203 263 343 203 211 345 220 215 a d d m u r
0000160 l \n # # # # # # # # # # # # # #
0000200 # # # # # # # # # # # # # # # #
0000220 # # # # # # # # \n i f t e s t
0000240 $ # – e q 1 ; t h e n
0000260 # 345 274 225 346 225 260 343 201 214 1 345 200 213
0000300 343 201 256 345 240 264 345 220 210 \n # 343 200 200 U R
0000320 L 343 201 256 343 202 242 343 202 257 343 202 273 343 202 271
0000340 343 203 201 343 202 247 343 203 203 343 202 257 \n 343 200 200
0000360 343 200 200 u r l c h e c k = $ ( w
0000400 g e t – – s p i d e r – n v
0000420 – t 1 $ 1 2 > & 1 |
0000440 g r e p – c ‘ 2 0 0 O K ‘
0000460 ) \n i f t e s t $ u r
0000500 l c h e c k – e q 1 ; t h e
0000520 n \n # 343 200 200 u r l 343 203 201 343 202 247 343
0000540 203 203 343 202 257 343 201 256 345 200 244 343 201 214 357 274
0000560 221 343 201 256 346 231 202 343 200 201 U R L 343 201 256
0000600 351 207 215 350 244 207 343 203 201 343 202 247 343 203 203 343
0000620 202 257 343 202 222 350 241 214 343 201 206 \n
0000640 d u p c n t = $ ( c a t m u
0000660 s i c _ u r l _ l i s t | g
0000700 r e p – c $ 1 ) \n
0000720 i f t e s t $ d u p c n t
0000740 – e q 0 ; t h e n \n # 343 200 200 U
0000760 R L 343 201 253 351 207 215 350 244 207 343 201 214 343 201
0001000 252 343 201 204 345 240 264 345 220 210 \n # 343 200 200 m
0001020 u s i c _ u r l _ l i s t 343 201 253
0001040 u r l 343 202 222 350 277 275 350 250 230 343 201 231 343
0001060 202 213 343 200 202 \n 343 200 200 343 200 200 e
0001100 c h o $ 1 > > m u s i c
0001120 _ u r l _ l i s t \n e l
0001140 s e \n # 343 200 200 U R L 343 201 253 351 207 215
0001160 350 244 207 343 201 214 343 201 202 343 202 213 345 240 264 345
0001200 220 210 \n # 343 203 241 343 203 203 343
0001220 202 273 343 203 274 343 202 270 * * * 343 201 223 343 201
0001240 256 U R L 343 201 257 343 201 231 343 201 247 343 201 253
0001260 347 231 273 351 214 262 343 201 225 343 202 214 343 201 246 343
0001300 201 204 343 201 276 343 201 231 343 200 202 * * * 343 202
0001320 222 350 241 250 347 244 272 343 201 227 343 201 246 347 265 202
0001340 344 272 206 \n e c h o ” 343
0001360 201 223 343 201 256 U R L 343 201 257 343 201 231 343 201
0001400 247 343 201 253 347 231 273 351 214 262 343 201 225 343 202 21
以下略

のような感じで表示されます。
不正な改行コードが入っている場合\r\nと記載されるということです。
見たところ、\r\nの記載はありません。
そこで、原始的な方法ですが、エラーメッセージの出ている行のコマンドの前後のスペースを打ち直すということを行い、正常に動作するようになりました。今後、WindowsのCygwin環境でコードを作成するのはやめにしようと思います。以下完成版のシェルスクリプトです。

#!/bin/bash
######################################
#addmurl (add url to music_url_list) #コマンド名 addmurl
######################################
if test $# -eq 1;then #引数が1個の場合
# URLのアクセスチェック
urlcheck=$(wget –spider -nv -t 1 $1 2>&1 | grep -c ‘200 OK’)
if test $urlcheck -eq 1;then
# urlチェックの値が1の時、URLの重複チェックを行う
dupcnt=$( cat ./music_url_list | grep -c $1 )
if test $dupcnt -eq 0;then
# URLに重複がない場合
# music_url_listにurlを追記する。
echo $1 >>music_url_list
echo $1 “を登録しました”
else
# URLに重複がある場合
#メッセージ***このURLはすでに登録されています。***を表示して終了
echo “このURLはすでに登録されています。”
fi
else
#URLチェックNGの場合
echo “正しいURLを指定してください。”
fi
else
#引数が1個以外の場合
echo “URLを1つだけ指定してください。”
fi

以上のシェルスクリプトを実行する時に、コマンド名の前に、いちいち./を付けなくてはなりません。そこで、パスの通ったディレクトリにシェルスクリプトをコピーすることにします。

パスの通っているディレクトリは、環境変数PATHを確認すれば、OKです。

$ echo $PATH
/home/user/bin:/home/user/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

ここで/home/user/bin /home/user/.local/bin などにパスが通っているのがわかります。今回は、/home/user/binにコマンドをコピーします。

$ mkdir /home/user/bin
$ cp ./addmurl /home/user/bin/addmurl

実行してみます

$ addmurl dummyurl
正しいURLを指定してください。

うまく行きました。

もうひとつ考慮しておくべきことがあります。それは、スクリプト中のファイルパスを相対参照にしておく必要があるということです。やることは簡単で、music_url_listを./music_url_listに変更してあげるだけです。

投稿者: linux32bit

2017/04よりlubuntuをDimension2400cにインストール。 Linuxの勉強を始める。覚書として学習記録をつづる。

コメントを残す