Shell Script

とりあえず、Shell Script 書けると便利。適当に書き捨てでいいのになと。今思いつくやつをとりあえず列挙してみる。テストしてないので、間違ってるかもしれないけど、あしからず。。

  • if文
#!/bin/sh

HOGE="hoge"
HOGE="$HOGE foo"

if [ "x$HOGE" = "x" ]; then
  echo "Not hoge"
else
  echo "$HOGE"
fi

if [ "x$HOGE" != "x" ]; then
  echo "$HOGE"
else
  echo "Not hoge"
fi
  • ループ
ITEMS="item1 item2 item3"
for it in $ITEMS
do
  echo "Current item is $it"
done

count="0"
while [ $count -lt 10 ]
do
  echo "count = $count"
  count=`expr $count + 1`
done
LOG_FILE=/tmp/hoge.log
if [ -f $LOG_FILE ]; then
  rm $LOG_FILE
fi

TEST_FILE=important.txt
if [ ! \( -f $TEST_FILE \) ]; then
  echo "funny" > $TEST_FILE
fi

TEST_DIR=/tmp/test
if [ -d $TEST_DIR ]; then
  rm $TEST_DIR
fi

if [ ! \( -d $TEST_DIR \) ]; then
  mkdir $TEST_DIR
fi
  • 外部コマンドの呼び出し
ERR_COUNT=`ls *.err | wc -l`
echo $ERR_COUNT

# たとえば、error番号 数字 その他説明 というようなファイルでエラー番号毎の数を調べるとか
RESULT=`cat error_list.txt | awk '{print $1}' | sort | uniq -c`
  • この辺を組み合わせて、たとえば特定のURLへのアクセスを連続して指定回数やるとか。
#!/bin/sh

ACCESS_URL=$1
MAX_COUNT=$2
if [ "x$ACCESS_URL" = "x" ]; then
  echo "$0 <access url> <count>"
  exit 1
fi

if [ "x$MAX_COUNT" = "x" ]; then
  echo "$0 $ACCESS_URL <count>"
  exit 1
fi

COUNT="0"
while [ $COUNT -lt $MAX_COUNT ]
do
  wget $ACCESS_URL
  COUNT=`expr $COUNT + 1`
done

wgetの-Oだったか-oオプションで出力ファイルを指定した方がいいかも。適当に流して、ご飯に行ったり別のお仕事をして、後で結果を見るとかある程度同じ作業の繰り返しなら楽できることがある。あとは、自分は記憶するのが下手なので、シェルスクリプトをファイルにして、どっかにおいとく。$HOME/scriptsとか。すると、後からなんかやったことあるけどってやつは、このフォルダを漁ってみつけることもある。数の大小の比較は、-lt, -gtとかある。確か、less than/greater thanとかから着てると思うけど。ifではじまったらその反対のfiと、do -> done とか。

あとは、特定のコマンドをしょっちゅう入力してたらそれを一回で済ませるようにするとか。

#!/bin/sh

cd $TEST_HOME
java -jar hoge.jar > foo.log 

これだけでも、cd $TEST_HOME するのがめんどいので、シェルにしてしまえば楽できる。この辺を覚えとけば、効率的じゃなくても、やりたいことを自動化できないかな。

その他、上の例のexprは、数字とかを足し算、引き算とかでつかう定石?みたいなので覚える。xargsを使うと標準入力の結果を引数にもってこれるとか。

たとえば、あるディレクトリ $1 以下で、拡張子 $2 のファイルを grep して $3 があるものを取り出すとか($数字はShell Scriptの引数)。

#!/bin/sh

find $1 -type f | grep $2 | xargs grep $3

みたいな風にするとできると思う。あとは、sed で置換ができて、awk で途中の値の取出しができるってことを覚えといて、結果にあわせて``で囲って、値を取り出す。basename/dirnameで、ファイル名/ディレクトリ名の取出しが出来る。(コマンドなので、BASE_NAME=`basename $TEST_FILE`みたいなのをする。)

私は、簡単なのでもシェルにして書くことを繰り返して覚えた。
今でも、使わないのはさっさとわすれちゃうけど、こんなのができるはずってのはだいたい覚える感じであとから調べて使う。


ということで、Shell Script使ったら楽できるかもというお話でした。

参考