対話式スクリプトを作成してみる
#!/bin/bash
echo "----------------------------"
echo "Please input"
echo "yes or no"
function ConfirmExecution() {
read input
if [ -z $input ] ; then
echo "let input"
ConfirmExecution
elif [ $input = 'yes' ] || [ $input = 'YES' ] || [ $input = 'y' ] ; then
echo "Exception"
elif [ $input = 'no' ] || [ $input = 'NO' ] || [ $input = 'n' ] ; then
echo "end"
exit 1
else
echo "Only yes or no"
ConfirmExecution
fi
}
# シェルスクリプトの実行を継続するか確認します。
ConfirmExecution
echo "----------------------------"
echo "hello world!"
実行ログ
$ bash example.sh
----------------------------
Please input
yes or no
hell
Only yes or no
let input
yes
Exception
----------------------------
hello world!
対話式プロセスを自動応答する
expectで標準出力に文字列と比較して、一致していた場合、sendの文字列を送るものになっている
先ほど作成したsh example.shをを自動応答するようにした
下記のコマンドでインストール
sudo yum install -y expect
#!/bin/bash
INPUT="yes"
expect << EOF
set timeout 5
spawn sh example.sh
expect "yes or no"
send "hell\n"
expect "Only yes or no"
send "\n"
expect "let input"
send "${INPUT}\n"
expect eof
EOF
出力ログ
sh example.exp
spawn sh example.sh
----------------------------
Please input
yes or no
hell
Only yes or no
let input
yes
Exception
----------------------------
全て決まったプロセスでコマンドを実行され、送るコマンドを決まっている場合には有効的ですが、想定外の入力を求められたときに標準入力で対応する、といった応用はうまくできませんでした。
プロセスの優先度を上げる
WEBAPIなどは安定してレスポンスと返せるようになる
微々たる違いかもしれません。
プライオリティの変更はroot出ないとできないのかも。
nice -n 10 server
# ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 0 1619 32753 0 80 0 - 47092 core_s pts/1 00:00:00 sudo
4 S 0 1620 1619 0 80 0 - 28852 - pts/1 00:00:00 bash
0 S 0 1790 1620 6 90 10 - 95874 - pts/1 00:00:01 server
0 R 0 1816 1620 0 80 0 - 28785 - pts/1 00:00:00 ps
既に実行しているプロセスの優先度を変更する
コマンドを入力してPIDを指定して変更します。
#!/bin/bash
echo "What is the command name"
read COM
renice 20 -p `(ps aux | grep ${COM} | grep -v grep | awk '{print $2}')`
What is the command name
server
1790 (process ID) old priority 10, new priority 19
リアルタイムにログの集中を行う
tail -f
と grep
でフィルタリングしてリアルタイムに監視し、ファイルに追記、awk
で抜き取りをしようと思いましたが、grepがバッファリングして困っておりましたがgrep --line-buffered
とawk '{print $7}{fflush()}'
で解決できました。
tail -f /efs/logs/*/app_logs | grep --line-buffered "foge" | awk '{print $7}{fflush()}' >> /efs/logs/refundlist.txt
上記のコマンドで複数ファイルを監視することができます。
複数のログファイルから特定のログを収集して、特定の文字列を抽出することを試みました。
また、ログの一部を引数にスクリプトを実行したい
xargs
は標準入力やファイルからリストを読み込みコマンドラインを作成することができます
xargs -L 1
とすることでスクリプトに1行ずつ引数にすることが可能です
苦労した点としては
grep
awk
はバッファしてしまうためリアルタイムにモニタリングすることができない
複数のログファイルの更新の監視にはtailf
が利用できない点でした
#!/bin/bash
#Extract UUID from all log files and write to refundlist.txt
cat /efs/logs/*/log | grep --line-buffered "Request" | awk '{print $2}{fflush()}' > /efs/logs/list.txt
#Request list is complete
#Continue to update the list
tail -f -n 0 /efs/logs/*/log | grep --line-buffered "Request" | awk '{print $2}{fflush()}' >> /efs/logs/list.txt &
#Process the list
cat /efs/logs/list.txt | xargs -L 1 sh /efs/sh/hoge.sh
#Continue to process the list
tailf -n 0 /efs/logs/list.txt | xargs -L 1 sh /efs/sh/hoge.sh