Skip to main content

6 posts tagged with "Unix"

View All Tags

UNIX: pushd, popd, dirs - ディレクトリスタックによる移動

· 2 min read
Yu Sasaki
Enterprise Security Manager / Advisor

シェルコマンドpushd, popd, dirsを用いて、ディレクトリスタックを使うことでディレクトリ間の移動を簡潔に行うTips。

使い方

pushdでスタックにジャンプしたいディレクトリを登録し、それをカレントディレクトリとする。popdで一番最後に登録したディレクトリを取り出し、それをカレントディレクトリとする。dirsでスタック内に登録されているディレクトリを表示。

スタックへディレクトリの登録

$ pushd /Applications/MAMP
/Applications/MAMP ~
$ pushd /var/log
/var/log /Applications/MAMP ~
$ pushd /etc
/etc /var/log /Applications/MAMP ~
$ dirs -v
0 /etc
1 /var/log
2 /Applications/MAMP
3 ~
$ popd
/var/log /Applications/MAMP ~
$ dirs -v
0 /var/log
1 /Applications/MAMP
2 ~
$ pwd
/var/log

ディレクトリ間の移動

上記のスタックの状態からホームディレクトリに移動するにはpushd +2を使用する。

$ pushd +2
~ /var/log /Applications/MAMP
$ pwd
/Users/yu
$ dirs -v
0 ~
1 /var/log
2 /Applications/MAMP
$ pushd +2
/Applications/MAMP ~ /var/log
$ pwd
/Applications/MAMP
$

aliasへの登録

当コマンドをより便利に使う為に、以下のaliasやよく使うディレクトリを予め~/.bash_profile等に登録しておくと良い。

alias pu='pushd'
alias po='popd'
alias dirs='dirs -v'
alias d='dirs'
alias pu1='pushd +1'
alias pu2='pushd +2'
alias pu3='pushd +3'
alias pu4='pushd +4'
alias pu5='pushd +5'
alias pu6='pushd +6'
alias pu7='pushd +7'
alias pu8='pushd +8'
alias pu9='pushd +9'

これで若干でも日々のタイプ量が減ると思うと、かなり良い。

参考サイト

Shell Script: testコマンドによる条件判定 (数値、文字列)

· 2 min read
Yu Sasaki
Enterprise Security Manager / Advisor

test_command 上表はshの組み込み、かつ外部コマンドでもあるtestコマンドの判定表。testコマンドは与えられた条件式に対して、終了コードに真「0」、**偽「1」**を返す。他のプログラミング言語の条件判定とは真偽の値の意味が逆なので違和感を覚えるが、例えばC言語のmainのreturn (システムへのreturn)は正常では0、異常では1を返す例と同様と考えるとしっくりくるかな。。

Shell Script: for文 - ワードリストに変数、コマンドを使用

· One min read
Yu Sasaki
Enterprise Security Manager / Advisor

以下のシェルスクリプトはfor文のワードリストに文字列変数を使用したもの。文字列はスペース区切でパラメータ変数に格納されloopする。また、ワードリストにバッククォートで括ったコマンドを指定すると、そのコマンドの実行結果がパラメータ変数に渡される。

#!/bin/sh
VARS="1 2 3 four five"
for VAR in $VARS
do
echo $VAR
done
echo ""
for LIST in `date`
do
echo $LIST
done

プロセスの監視&自動復旧(簡易版)

· One min read
Yu Sasaki
Enterprise Security Manager / Advisor

プロセス監視シェルスクリプトの実行結果

先日書いたシェルスクリプトでプロセスを監視し自動実行&自動killのシェルスクリプトは、その後結局使わず、さらに簡易的なコードで済ませました。

クエリーサーバのチェックスクリプト

scheckp.sh

#!/usr/bin/sh
while true
do
isAliveSev=`ps -ef | grep "/server" | grep -v grep | wc -l`
if [ $isAliveSev = 1 ]; then
echo "o:server process"
else
echo "x:server process"
/ret/sev/server &
fi
sleep 300 # モニター間隔(秒単位)
done

エンジンサーバのチェックスクリプト

echeckp.sh

#!/usr/bin/sh
while true
do
isAliveEng=`ps -ef | grep "/engine" | grep -v grep | wc -l`
if [ $isAliveEng = 1 ]; then
echo "o:engine process"
else
echo "x:engine process"
/ret/eng/engine &
fi
sleep 300 # モニター間隔(秒単位)
done

シェルスクリプトでプロセスを監視し自動実行&自動kill

· 5 min read
Yu Sasaki
Enterprise Security Manager / Advisor

追記プロセスの監視&自動復旧(簡易版)

今ある検索エンジンのデバッグを行っていますが、事情により短期間ですがクローズドな環境で運用されることになりました。構成は大きく分けてエンジンモジュールサーバ、クエリーモジュールサーバの二つのサーバからなっています。

デバッグはまだ途中なので、運用中にクエリーサーバorエンジンサーバのどちらか、もしくは両方が落ちる可能性もあります。落ちた場合は、手動で起動しなおすことになっていますが、せっかくなので自動化しよう。と、考えました。最初はcronデーモンを用いようと思いましたが、プロセスの監視(dead or alive)の仕方が分からず(調べきれず)、シェルスクリプトを用いることにしました(とは言うもののシェルスクリプトを使うのも初めてでした)。

クエリーサーバ&エンジンサーバのプロセスを一定の間隔で監視し、一方が何らかの原因で落ちた際は、再び二つのプロセスを再実行するようなスクリプトの作成を試みました。ここで、以下の要因を考慮に入れる必要がありました。

  • エンジンorクエリーのどちらかが落ちたら、両システムも再起動する
  • 起動順序はエンジン→クエリー
  • エンジンの起動中にクエリーが起動するとエラー
  • 同じターミナルではエンジン(サーバ)とサーバがうまく動作しない(もともと別々のマシンで動作させるものでもある)→別の端末でそれぞれ実行する(やっかい)

そこで、即席ではありますが、以下の二つのシェルスクリプトを作成しました。

検索エンジンモジュール用監視スクリプト(Echeckp.sh)

#!/usr/bin/sh
inter=3 # プロセスの監視間隔
wait=5 # serverの起動待ち時間
while true
do
isAliveSev=`ps -ef | grep "/server" |
grep -v grep | wc -l`
if [ $isAliveSev = 1 ]; then # serverが動いているか
echo "o:serverプロセス"
else
echo "x:serverプロセス"
pidEng=(`ps -ef | grep "/engine" |
grep -v grep | awk '{ print $2; }'`)
kill $pidEng
/ret/eng/engine &
flag=true
while $flag
do
echo "serverの起動待ち"
reAliveSev=`ps -ef | grep "/server" |
grep -v grep | wc -l`
if [ $reAliveSev = 1 ]; then
flag=false
fi
sleep $wait
reAliveEng=`ps -ef | grep "/engine" |
grep -v grep | wc -l`
if [ $reAliveEng = 0 ]; then # 両方止まったとき
/ret/eng/engine &
fi
done
fi
isAliveEng=`ps -ef | grep "/engine" |
grep -v grep | wc -l`
if [ $isAliveEng = 1 ]; then # engineが動いているか
echo "o:engineプロセス"
else
echo "x:engineプロセス"
pidSev=(`ps -ef | grep "/server" |
grep -v grep | awk '{ print $2; }'`)
kill $pidSev
/ret/eng/engine &
flag=true
while $flag
do
echo "serverの起動待ち"
reAliveSev=`ps -ef | grep "/server" |
grep -v grep | wc -l`
if [ $reAliveSev = 1 ]; then
flag=false
fi
sleep $wait
reAliveEng=`ps -ef | grep "/engine" |
grep -v grep | wc -l`
if [ $reAliveEng = 0 ]; then # 両方止まったとき
/ret/eng/engine &
fi
done
fi
sleep $inter # モニター間隔(秒単位)
done

続いて、

検索クエリーサーバモジュール用監視スクリプト(Scheckp.sh)

#!/usr/bin/sh
inter=3 # プロセスの監視間隔
wait=3 # engineの起動待ち時間
while true
do
isAliveEng=`ps -ef | grep "/engine" |
grep -v grep | wc -l`
if [ $isAliveEng = 1 ]; then
echo "o:engineプロセス"
else
echo "x:engineプロセス"
pidSev=(`ps -ef | grep "/server" |
grep -v grep | awk '{ print $2; }'`)
kill $pidSev
flag=true
while $flag
do
echo "engineの起動待ち"
reAliveEng=`ps -ef | grep "/engine" |
grep -v grep | wc -l`
if [ $reAliveEng = 1 ]; then
flag=false
fi
sleep $wait
done
/ret/sev/server &
fi
isAliveSev=`ps -ef | grep "/server" |
grep -v grep | wc -l`
if [ $isAliveSev = 1 ]; then
echo "o:serverプロセス"
else
echo "x:serverプロセス"
pidEng=(`ps -ef | grep "/engine" |
grep -v grep | awk '{ print $2; }'`)
kill $pidEng
flag=true
while $flag
do
echo "engineの起動待ち"
reAliveEng=`ps -ef | grep "/engine" |
grep -v grep | wc -l`
if [ $reAliveEng = 1 ]; then
flag=false
fi
sleep $wait
done
/ret/sev/server &
fi
sleep $inter # モニター間隔(秒単位)
done

と記述し、それぞれ別の端末でshコマンドで実行します。その際chmodで実行権限を与えておくことを忘れないようにします。また、待ち時間は状況に合わせて変更します(初期設定は3秒おきにチェック)。
一応、これで期待した自動復旧の動作はしましたが、冗長なコードの気がしますし、今回の問題解決にはもっと上手い手段があると思いました。

まぁ、それはそれ。
本分のデバッグ作業に戻りますか。
にしても、シェルスクリプトも興味深いです。