bashまとめ


###対話式スクリプトを作成してみる

```example.sh
#!/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
```

```example.exp
#!/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を指定して変更します。

```set-process-priority.sh
#!/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`が利用できない点でした


[【 xargs 】コマンド](https://www.atmarkit.co.jp/ait/articles/1801/19/news014.html)

```Logprocessing.sh
#!/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
```