HOME » 備忘録 » 2017 » シェルメモ

シェルメモ

よく使うように見せかけて使わないぐらいの覚えられない程度のコマンドやシェルスクリプト

作成日時:2017-10-03 / 最終更新:2018-02-20

使用環境はCentOS6系、7系。
Bashを使用。

ioniceを使用してI/O優先度を指定

CentOSではUtil-linuxパッケージに内包されているコマンド
I/Oスケジューラーに対する優先度の設定を行う

$ time ionice -c3 -n 4 tar zcvfp ./html /tmp/html-bk`date +%Y%m%d`.tar.gz

cstreamを使用してI/O負荷軽減

CentOSではcstreamコマンドは標準では入っていないので別途インストールが必要
例では3MB/secで書き出している

$ time tar zcvfp ./html | cstream -t $((3*1024*1024)) > /tmp/html-bk`date +%Y%m%d`.tar.gz

BOT系のアクセス数をカウント

UAを小文字に変換した後比較していく。

$ awk -F '"' 'tolower($6) ~ /bot|spider|craw|cloudfront|http|scrap/' access_log | wc -l

各ユーザのcrontab出力

passwdファイルからユーザ名を取得してcrontabの設定を出力する、root権限で実行する。

# for user in $(cut -f1 -d: /etc/passwd); do echo $user; crontab -u $user -l; done

# ほどくとこんな感じ
for user in $(cut -f1 -d: /etc/passwd);
	do
		echo $user;
		crontab -u $user -l;
	done

複数のファイルから特定の文字列を探す

今いるディレクトリから再帰的にphpファイルの中身から休暇を探し出す。基本見つからない。

$ find . -type f -name "*.php" | xargs grep "kyuuka"

暫定でSQLバックアップ

SQLバックアップ、cronに入れておいてリネームしながら転送させておけばとりあえず夜は安心して眠れる。

sqlbackup.sh
#!/bin/bash
cd /var/backup
mysqldump –defaults-file=./mysqldump.conf -A > backup.sql
mysqldump.conf
[mysqldump]
user=test
password=test

代替treeコマンド

treeコマンドがない環境で階層表示

$ pwd;find . | sort | sed '1d;s/^\.//;s/\/\([^/]*\)$/|–\1/;s/\/[^/|]*/| /g'

ファイル名でマルチバイトや特殊文字を使用しているものを抽出

数字英字.-以外の文字を含むファイルを抽出、パイプでつないでegrep -vで除外ディレクトリを指定したり、wcでカウントしたりすると仕事できる人に見える

$ find . -regex \./.*/[^/]*[^0-9a-zA-Z/\.\-]+[^/]*

Webサイトをローカルにクローンを作る

まだ検討の余地あり

$ wget -p -H -E -nH -nv -k –http-user=basic-user –http-password=basicPW –domains "get-target.url" -r http://get-target.url/

間隔的にコマンドを実行する

5秒感覚でdateコマンドとdfコマンドの結果をテキストファイルに出力、調査用

$ while true; do date >> moni_storage.txt; df -m >> moni_storage.txt; sleep 5; clear; done;

# ほどくと以下になるので、間隔的に何かを実行する際は便利。
$ while true;
	do
		date >> moni_storage.txt;
		df -m >> moni_storage.txt;
		sleep 5;
		clear;
	done;


access_logを日時でソート

ロードバランサーなど使用している場合や、日付毎に出力してるなどログファイルを結合したときに見やすく並び替えする。

$ cat access_log | sed -e "s:/Jan/:/01/:" -e "s:/Feb/:/02/:" -e "s:/Mar/:/03/:" -e "s:/Apr/:/04/:" -e "s:/May/:/05/:" -e "s:/Jun/:/06/:" -e "s:/Jul/:/07/:" -e "s:/Aug/:/08/:" -e "s:/Sep/:/09/:" -e "s:/Oct/:/10/:" -e "s:/Nov/:/11/:" -e "s:/Dec/:/12/:" | sort -t " " -k 4.8,4.11 -k 4.5,4.6 -k 4.2,4.3 -k 4.13,4.14 -k 4.16,4.17 -k 4.19,4.20 > access_log.sorted

最終修正日時(modify time)が3日前までのものを抽出

なんかやらかした時に変更があったファイルを抽出するのに便利。
最終アクセス日時(access time)が知りたい場合はオプションを-atimeに変更

$ find . -mtime -3 -ls

日時範囲を指定して検索

-newermt以外にも-newerat,-newerctが使用でき、それぞれ mtime,atime,ctimeに対応。

$ find . -newermt '2013-03-14' -and ! -newermt '2013-03-16'

多言語サイトの本番反映用置き換えスクリプト

多言語展開しているサービスのプログラムを一気に置き換えないといけなかった時に使用。
レガシーなシステムにデプロイシステムやロードバランサーなどあるわけない。

#!/bin/bash

basePath="/var/www/html";
# 置き換えるファイル名 test.php.new → test.php
File="test.php";
# 言語固有
spPath=(en tw zh ko);
# バックアップファイルのオプション e.g.:test.php_bk20171010
mvOption="-b --suffix=_bk$(date +%Y%m%d)";

for i in ${spPath[@]}
do
    # バックアップを作成しながら置き換える /var/www/html/en/XXX.php.new → XXX.php
    mvCommand='mv $mvOption "$basePath/$i/$File.new" "$basePath/$i/$File"';
    eval ${mvCommand};
done

分単位でアクセスログをカウント

DoSられた時の報告用、引数でファイルを指定して使用。

#!/bin/bash
for i in `seq -w 0 59`;
do
	grepdate="15/Oct/2017:12:$i";
	result=`cat $1 | grep $grepdate | wc -l`;
	echo "|$grepdate|$result|";
done;

再帰的にListコマンドを行う

パーミッションなどのエビデンス用。

$ ls -Ralr

ファイルとディレクトリを分けて、再帰的にパーミッションを変更

あるよね。

# ファイルを再帰的に640へ
$ find . -type d -print | xargs chmod 640
# ディレクトリを再帰的に750へ
$ find . -type d -print | xargs chmod 750

HTMLファイルを探索

CMSに移設しきれていない物理ファイルを探し出す際に使用。

$ find . -name "*.html" -or -name "*.htm" -or -name "*.shtml"

POST

curlコマンドでただPOSTするだけ

文字列をPOST
#!/bin/bash
url="http://hoge.hoge/hoge.php"
base64=`echo -n "string" | base64`
curl -F 'key1=value1'  -F 'key2=value2' -F "key3=$base64" $url
ファイルをPOST
#!/bin/bash
url="http://hoge.hoge/hoge.php"
curl -F 'post=@/home/user/test.txt' $url

Swap使用量の確認

アスタリスク部分にはPIDが入るのでpsコマンドで確認しながら使用。

# grep VmSwap /proc/*/status | sort -k 2 -r | head

ApacheログからクローラーやBOTを除外

っぽいやつを消す。

$awk -F '"' '$6 !~ /bot|spider|crawler|Amazon CloudFront|http/' access_log > no_bot.log

直下のファイルを一つずつコマンドに渡す

一気に処理したい時に。

$ls *.log | xargs -l --replace=FILENAME echo FILENAME

一度しか発生していない404を除外

404だけ抽出したものに対して

$awk -F '"' 'a[$2]++' 404.log > 404.awklog

access_logからリクエストのみ抽出

$awk -F '"' '{print $2}' access_log > request.log

access_logからRewriteRuleの使用回数をカウント

処理速度の為、最初に300系のログだけを抽出。
ルールの正規表現部分だけ抽出したファイルを用意、この時最終行を空改行しないと完走しない謎。
第一引数にaccess_log、第二引数に正規表現ファイルを指定してリダイレクションで保存するだけ。

実行例
$ sh check.sh access_300.log Rule.txt > results.txt

スクリプト
#!/bin/sh
logfilename=$1
matchfilename=$2
cat $matchfilename | while read line
do
  RULE=`echo ${line} | sed -e "s/[\r\n]\+//g"`
  VAR=`grep -E "$RULE" ${logfilename} | wc -l`
  echo $RULE"\t"$VAR
done

access_logからRewriteRuleマッチするもののみ抽出

#!/bin/sh
logfilename=$1
matchfilename=$2
cat $matchfilename | while read line
do
  RULE=`echo ${line} | sed -e "s/[\r\n]\+//g"`
  grep -E "$RULE" ${logfilename} >> Match$1
done

ソートしないで重複している行の削除

フィールドを指定して削除するときはuniqコマンドのほうでやったほうがいい

$ awk '!a[$0]++' request.log > dup_request.log

リクエストパスだけ抽出

$ awk -F '"' '{print $2}' 301-all.log > request.log
$ awk -F ' ' '{print $2}' request.log > awk-request.log

改行コードの確認と置換

$ cat -e FILE
$ sed -e 's/^M//g' FILE > sed-FILE 

ctimeを指定してファイル作成

差分取ったりするテスト用に。

$touch -d "2017/12/20 14:18:00" test.lock