Tag: bash Tag: シェルスクリプト

 主にUbuntu14.04でのbash上でスクリプトを動かした時のメモです。基本的なものは、CentOSなどでも有効ですが、オプションが微妙に異なる事があります。

Linux関係でのシェルスクリプトメモ


基本

実行結果を変数に格納「$()」とバッククオート

$(コマンド) や バッククォートでコマンドを囲むと次の様に変数に代入して使ったり出来ます。バッククオートの方がシンプルで簡潔な感じがしますが、初心者がシングルクォートと間違えたりする事あるかもしれません。また、$()は、ネストして使うことも出来ます。

KEKKA=$(ls -1tr | tail -n 1)

最も新しいタイムスタンプのファイル名がKEKKAに代入されます。

DATESTR=$(date +%Y_%m_%d)

今日が2022年2月3日なら、DATESTRが「2022_02_03」となります。


TSVファイル加工

1行目をカット、3列目のみ使う、項目の右端に半角カンマ付加、改行削除

sed 1d samplefile.tsv | cut -f3 | awk '{print $1","}' | tr -d "\n"

緯度、経度、値のようなデータから、緯度のみを取り出して1行にする。以下の様な内容になる。

35.53527961,35.54406335,35.55200615,35.55790072,35.56482473,35.57177418,35.57874627,35.58573235,35.59272382,35.60126796,35.60586475,35.61326295,35.62195623,35.62986071,35.63862818,35.64609106,35.65062147,35.65303037,35.65693338,35.66330111,35.67129473,35.67936753,35.68744228,35.69550919,35.70357795,35.71164548,35.71971557,35.72778169,35.73585154,35.74392086,35.75180884,35.75663327,35.75968077,35.76458262,35.77259184,35.77421234,35.7827242,35.79127109,35.79994844,35.80675105,35.8153858,35.82371878,35.83136962,35.83802896,35.84503731,
----以下省略-----




TSVファイルに日付情報をファイル名から追加してコード毎にまとめる

  • 2017-01-30
  • CentOS release 6.3
  • ファイルは「2017-01-30-14.txt」の形式で最後の「-14」が時間。これを後ほどグラフ作成で使いたいので"2017-01-30-14"を"2017-01-30 14:00:00"の形式にしたい。
#!/bin/bash
 
cd hogehoge
 
WORKFNAME1=view2_1.temp
WORKFNAME2=view2_2.temp
 
for F in near_????-??-??-??.txt; do
    awk -vOFS="\\t" -v fname="$F" -F"\\t" '{print $1, fname , $4 }' $F
done \
 | sort -k1n  > $WORKFNAME1
 
sed -e "s/\-\([0-9]\{2\}\)\.txt/ \1:00:00/" -e "s/near_//" $WORKFNAME1 > $WORKFNAME2
 
for NO in `cut -f1 $WORKFNAME2 | uniq`; do grep ^${NO}[[:space:]] $WORKFNAME2 > point_${NO}.tsv; done
 
 
rm $WORKFNAME1
rm $WORKFNAME2



同様の処理を複数のフォルダに行う場合に関数化

#!/bin/bash
 
datahenkan_tsv() {
 
# dirctory
cd $1
 
WORKFNAME1=view2_1.temp
WORKFNAME2=view2_2.temp
 
for F in near_????-??-??-??.txt; do
    awk -vOFS="\\t" -v fname="$F" -F"\\t" '{print $1, fname , $4 }' $F
done \
 | sort -k1n  > $WORKFNAME1
 
sed -e "s/\-\([0-9]\{2\}\)\.txt/ \1:00:00/" -e "s/near_//" $WORKFNAME1 > $WORKFNAME2
 
for NO in `cut -f1 $WORKFNAME2 | uniq`; do grep ^${NO}[[:space:]] $WORKFNAME2 > point_${NO}.tsv; done
 
 
rm $WORKFNAME1
rm $WORKFNAME2
 
}
# ----- ^^^^^ -----
 
datahenkan_tsv dirsampe1
datahenkan_tsv dirsampe2
datahenkan_tsv dirsampe3
datahenkan_tsv dirsampe4
datahenkan_tsv dirsampe5




サーバー管理

ディスク空きが少なくなったらメールする

dfコマンドを利用してデバイスひとつの空きが少なくなったことを利用率(%)で大凡判断して指定した%を越えていたらメールを送る。(2022-02-03)

#!/bin/bash
 
TO_MAIL=hogehoge@iscb.net
SERVER_ID=server1234-01
CHKDEVICE=/vda3
CHKPER=95
USEPER=$(df | grep "$CHKDEVICE" | tr -s " " | cut -d" " -f 5 | tr -d "%")
 
#echo check device:$CHKDEVICE / test $USEPER -gt $CHKPER
# true:0  / false:1
#test $USEPER -gt $CHKPER
#echo $?
 
 
if test $USEPER -gt $CHKPER; then
        df -h | mail -s "$SERVER_ID: disk space small / now $USEPER % use" $TO_MAILt
fi


ディスク使用増加をduでチェック

  • 2022-02-12
  • ディスクの使用増加を幾つかのフォルダに注目する為に、duコマンドで定期的にチェックし、チェックした日時を追加してTSV形式で保存。
#!/bin/bash
 
# 2022-02-12
 
DT=$(date +"%Y-%m-%d %H:%M");(du -d1 /;du -d1 /home; du -d1 /home/kansoku) | sed "s/^/${DT}\t/g" \
    >> disk_use_log_$(date +"%Y-%m").tsv
  • ポイント
    • $(コマンド) で実行結果を変数に代入
    • sedでの行先頭の検索は「^」
    • sed置き換え文字のタブ記号は「\t」


FTP転送のログを確認

2026-02-08

  • OS: CentOS6.5
  • proftpdでログイン成功したログをカウント。成功が過去2時間程度で0件なら注意メール。
  • OSやftpの種類が変わった場合はスクリプト調整が必要と思われる。
  • 送信先メールアドレスは、実際にメールを送る先のメールアドレスを指定。
  • 送信元メールアドレスは、Fromに指定する実際のメールアドレスを指定する。ドメインが存在しないメールアドレスの場合には、メールが届かいない事が増えている。
#!/bin/bash
 
SERVERID=OI21
LOGFILE=/var/log/secure
TEMPFILE=proftpd.temp
MAILTO=送信先メールアドレス
MAILFROM=送信元メールアドレス
 
grep -e "proftpd"  $LOGFILE | grep successful > $TEMPFILE
 
 
# 1. 現在の「月 日 時」を取得
now_word=$(LANG=C date +"%b %e %H")
# 2. 1時間前の「月 日 時」を取得
prev_word=$(LANG=C date -d '1 hour ago' +"%b %e %H")
 
# 3. それぞれの件数をカウント
count_now=$(grep -c "^$now_word" $TEMPFILE)
count_prev=$(grep -c "^$prev_word" $TEMPFILE)
 
# 4. 合計を計算
total=$((count_now + count_prev))
 
echo total $total
 
# 5. 合計が0ならメール送信
if [ $total -eq 0 ]; then
    echo "直近2時間のログが0件です。確認してください。" | \
        mail -s "$SERVERID:FTPログ監視アラート" -r "$MAILFROM" $MAILTO
fi
 
# test
if [ $total -le 60 ]; then
    echo "直近2時間のログが合計 ${total} 件です。60件を下回ったため通知します。" | \
        mail -s "$SERVERID:FTPログ監視アラート" -r "$MAILFROM" $MAILTO
fi
 
rm $TEMPFILE



grep

検索したいキーワードが2つ以上ある

grep -e キーワード1  -e キーワード2  -e キーワード3  検索対象ファイル

この場合、キーワード1、キーワード2、キーワード3のどれか一つでも存在する行が対象。

すべてのキーワードが存在する行を検索する場合は、パイプを使います。

grep キーワード1  検索対象ファイル  |  grep  キーワード2 | grep キーワード3

awkを使う場合は、次のようにしても全てのキーワードを含む行を検索できます。

awk ' /キーワード1/ && /キーワード2/ && /キーワード1/ ' 検索対象ファイル

awkでキーワードを複数あり、そのうちのどれか一つでも一致する場合なら、以下のようになります。

awk ' /キーワード1/ || /キーワード2/ || /キーワード1/ ' 検索対象ファイル


mail

crontabで実行した時の文字化け解消

2026-02-09

echo "直近2時間のログが合計 ${total} 件です。60件を下回ったため通知します。" | \
       mail -s "$SERVERID:FTPログ監視アラート" -r "送信元メールアドレス" \
       送信先メールアドレス

は、CentOS6.5の環境でのシェルスクリプトの一部です。ログインして実行する場合はメールが送信されますが、crontabで同じスクリプトを実行すると、メールが届かない。調べると、文字化けが発生したために、迷惑メールとして判断されてしまったようです。
 文字化けの原因は、crontabで実行される際の環境が、ログインした時と異なる為、今回はcrontabでは、文字コードの扱い(ロケール,LANG)が日本語を前提になっていない事です。
 したがって、スクリプトの冒頭で、文字コードを指定します。以下のようにします。

 #!/bin/bash

export LANG=ja_JP.UTF-8

メール送信先を複数指定

 上の例を修正すると、以下のように、送信先の部分でメールアドレスを空白で区切って指定します。

echo "直近2時間のログが合計 ${total} 件です。60件を下回ったため通知します。" | \
       mail -s "$SERVERID:FTPログ監視アラート" -r "送信元メールアドレス" \
       送信先メールアドレス1  送信先メールアドレス2  送信先メールアドレス3

CCやBCCで送る

CCは、-c メールアドレス、BCCは、-b メールアドレス と指定する事が出来ます。


ファイル転送関係


expect

  • 2022-02-15
  • 対話形式の処理をスクリプト内で行う→パスワード入力が必要な処理を自動化出来る。
  • 例えば、sftpでの処理を自動化する例
  • 以下のような内容でsftp_expect.sh を作成して実行すると、「アカウト名@IPアドレス」と「アカウト名のパスワード」で接続したサーバのファイルをダウンロード。
#!/usr/bin/expect
 
spawn sftp アカウト名@IPアドレス
expect "password:"
send "アカウト名のパスワード\n"
expect "sftp> "
send "cd point/2022/02\n"
expect "sftp> "
send "get M*\n"
expect "sftp> "
send "quit\n"
interact