ラベル シェルスクリプト の投稿を表示しています。 すべての投稿を表示
ラベル シェルスクリプト の投稿を表示しています。 すべての投稿を表示

2015-08-27

シェルスクリプトで変数のデフォルト値を使う

${var:-foo}変数varが未定義の時fooを返す
${var:=foo}変数varが未定義の時fooを代入する。
${var:+foo}変数varに値がセットされているときfooを返す
${var:?puyo}変数varが未定義の時"puyo"を出力しexit 1する

な感じで使えます(ノ゚⊿゚)ノ

2015-08-26

cronから起動されたスクリプトの多重起動チェック

多重起動チェックについてググってみると次のような例が多く見つかりました

[[ $$ != `pgrep -fo "$0"`  ]] echo "$0 is already running" && exit 2

これは、自身と同じプロセス名を検索して、

そのもっとも古いプロセスIDが自身のプロセスIDと一致していればおーけー

という処理になります。

ただ、これは直接スクリプトを実行した場合にのみ有効で

cronなどから子プロセスそしてスクリプトを実行した場合は

$$は子プロセスとして起動されたスクリプトのプロセスID

pgrep -fo "$0"で引っかかってくるのが起動元の親プロセスのIDとなり

一致しないので、多重起動として扱われてしまいました(´・ω・`)

これに対応するため、親プロセスIDが格納される$PPIDとの比較も追加して次のようにしてみました

[[ $$ != `pgrep -fo "$0"`  ]] && [[ $PPID != `pgrep -fo "$0"`  ]] && echo "$0 is already running" && exit 2

これで、直接起動した場合も、cronなどから子プロセスとして起動した場合も多重起動チェックできますヾ(*・ω・)シ

シェルスクリプトで変数に格納された文字列から部分文字列を抽出する

str=abcdefg

echo ${str:0:2}  # ab
echo ${str:2:2}  # cd

な感じ(ノ゚⊿゚)ノ

2014-11-05

シェルスクリプトで変数展開時に値の置換/削除処理を行う

記述動作対応するsedコマンド例
${変数名#*c}前方一致でのマッチ部分削除(最短マッチ)sed "s/^.*?c//"
${変数名##*c}前方一致でのマッチ部分削除(最長マッチ)sed "s/^.*c//"
${変数名%*c}後方一致でのマッチ部分削除(最短マッチ)sed "s/.*?c$//"
${変数名%%*c}後方一致でのマッチ部分削除(最長マッチ)sed "s/.*c$//"
${変数名/*c/def}文字列置換(最長マッチで最初にマッチしたもののみ)sed "s/.*c/def/"
${変数名//*c/def}文字列置換(最長マッチでマッチしたものすべて)sed "s/.*c/def/g"

置換時の最短マッチの書き方は不明・・・

*cだとabcabcに対してabcではなくabcabc全体にマッチしてしまう(´・ω・`)

スクリプト内部で子プロセスをバックグラウンド実行し、親プロセスと一緒に終了する

子プロセスはバックグラウンドで動作し、1秒おきに.を出力

親プロセスとしては、10秒間スリープして"finish."を表示するというもの

スクリプトの中身はこんな感じ

$ cat test.sh 
#! /bin/bash
ppid=$$
while( ps -p $ppid > /dev/null 2>&1 );do
  echo -n "."
  sleep 1
done &

sleep 10
echo -e "\nfinish."

実行するとこうなる
$ ./test.sh 
..........
finish.
親プロセスが終了すると、バックグラウンドで実行していた.を出力する子プロセスも終了してますねヾ(*・∀・)ノ"

シェルスクリプトで変数に格納した改行を扱う

変数msgに改行を含む値を格納してみる
$ msg="a
> b
> c"
これを表示してみると
$ echo $msg
a b c
といった具合に半角スペースに置換されてしまっている

改行として表示するにはダブルクォーテーションで括ってあげる必要があるらしー
$ echo "$msg"
a
b
c