整理汇总从网上、书上看到的bash脚本的基本技巧,实验记录。
1. select 语句与异常处理
修改/etc/hosts文件增加3条记录
127.0.0.1 server01.demo.com
127.0.0.1 server02.demo.com
127.0.0.1 server03.demo.com
用ssh-keygen -t rsa 生产密钥,并用cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys发布
demo10.sh
#!/bin/bash
servers=(
"server01.demo.com"
"server02.demo.com"
"server03.demo.com"
"QUIT"
)
PS3="connect to the server?"
select server in "${servers[@]}"; do
if [[ -z $server ]]; then
echo "select the number"
continue
fi
if [[ $server == "QUIT" ]]; then
echo "quit!"
exit 0
fi
echo "connect $server"
ssh "$server"
done
oliver@bigdatadev:~/_src/shell$ ./demo10.sh
1) server01.demo.com 3) server03.demo.com
2) server02.demo.com 4) QUIT
connect to the server?1
connect server01.demo.com
Welcome to Ubuntu 14.04.3 LTS (GNU/Linux 3.19.0-25-generic x86_64)
* Documentation: https://help.ubuntu.com/
*** 需要重启系统 ***
Last login: Sun Jul 24 17:15:33 2016 from localhost
oliver@bigdatadev:~$ exit
注销
Connection to server01.demo.com closed.
connect to the server?4
quit!
oliver@bigdatadev:~/_src/shell$
2. 配置文件、管道处理重复操作(管理多台机器)
#!/bin/bash
servers=(
"server01.demo.com"
"server02.demo.com"
"server03.demo.com"
)
for server in ${servers[@]}; do
ssh "$server" "$@"
done
oliver@bigdatadev:~/_src/shell$ demo11.sh hostname
bigdatadev
bigdatadev
bigdatadev
oliver@bigdatadev:~/_src/shell$
配置文件和管道
$@参数列表、sed 在每行开头增加服务器名、&并发执行,wait等待完成,用group提取输出
运行脚本是利用< servers.txt 实现输入,>output.txt输出
#!/bin/bash
while read server; do
ssh -n "$server" "$@" 2>&1 | sed "s/^/$server: /" &
done
wait
oliver@bigdatadev:~/_src/shell$ ./demo12.sh "vmstat 1 5" < servers.txt > output.txt
oliver@bigdatadev:~/_src/shell$ grep "server01" < output.txt
server01.demo.com: procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
server01.demo.com: r b swpd free buff cache si so bi bo in cs us sy id wa st
server01.demo.com: 4 1 0 2114224 92244 1106820 0 0 85 53 76 283 2 1 97 1 0
server01.demo.com: 2 0 0 2114252 92244 1106876 0 0 0 0 57 203 0 0 99 1 0
server01.demo.com: 2 0 0 2114252 92244 1106876 0 0 0 0 55 172 0 1 99 0 0
server01.demo.com: 2 0 0 2114252 92244 1106876 0 0 0 0 50 170 1 0 99 0 0
server01.demo.com: 4 0 0 2114252 92244 1106876 0 0 0 0 44 159 0 1 99 0 0
oliver@bigdatadev:~/_src/shell$
在脚本中处理重定向文件输入
#!/bin/bash
file=$1
shift
while read server; do
ssh -n "$server" "$@" 2>&1 | sed "s/^/$server: /" &
done <"$file"
wait
oliver@bigdatadev:~/_src/shell$ ./demo13.sh servers.txt free
: ssh: Could not resolve hostname : No address associated with hostname
server02.demo.com: total used free shared buffers cached
server02.demo.com: Mem: 4039084 1924268 2114816 14640 92376 1106892
server02.demo.com: -/+ buffers/cache: 725000 3314084
server02.demo.com: Swap: 3905532 0 3905532
server03.demo.com: total used free shared buffers cached
server03.demo.com: Mem: 4039084 1921456 2117628 14640 92376 1106892
server03.demo.com: -/+ buffers/cache: 722188 3316896
server03.demo.com: Swap: 3905532 0 3905532
server01.demo.com: total used free shared buffers cached
server01.demo.com: Mem: 4039084 1921192 2117892 14640 92376 1106892
server01.demo.com: -/+ buffers/cache: 721924 3317160
server01.demo.com: Swap: 3905532 0 3905532
oliver@bigdatadev:~/_src/shell$
3. 进程监控
#!/bin/bash
function monitor{
pgrep -x $1 >/dev/null 2>&1
return $?
}
if monitor "httpd"; then
status="up"
else
status="down"
fi
while [[ true ]]; do
monitor "httpd"
rc=$?
if [[ $rc -eq 0 && $status != "up" ]]; then
status="up"
logger -t "my_monitor" "httpd is up."
fi
if [[ $rc -ne 0 && $status != "down" ]]; then
status="down"
logger -t "my_monitor" "httpd is down."
fi
sleep 10
done
4. rsync、tee和mail
使用rsync备份、tee输出到文件和管道、mail发邮件,{}将命令放在一起重定向输出。
#!/bin/bash
TEMPFILE=/tmp/snashot.log.$$
{
echo "=== Rsync from /data/ to snapshot/: ${data}"
mount -o rw, remount /dev/sdc
rsync -av /data/ /snapshot/
rc=$?
mount -o ro,remount /dev/sdc
if [[ $rc -eq 0 ]]; then
echo "=== Snapshot succeded: ${date}"
SUBJECT="Snapshot report {Succeeded}:
else
echo "=== Snapshot failed with rc=$rc: ${date}:
SUBJECT="Snapshot report {Failed}"
fi
} 2>&1 | tee $TMPFILE | logger -t "snapshot"
iconv -f utf8 -t gb2312 $TMPFILE | mail -s "$SUBJECT" admin@example.com