2012/10/31
hbstudy まとめ
先日参加した hbstudy #38 ハンズオンの
課題 の幾つかを
シェルのみ 縛りで回答してみる。
流石にシェルのみで解く場合はワンライナーは無理なので、
普通のシェルスクリプトの型式で記述している。
- 問題1: ユーザの抽出
-
/etc/passwd から、ユーザ名を抽出したリストを作って下さい
1IFS=: 2while read id other 3do 4 echo ${id} 5done </etc/passwd
IFS を : に変更して /etc/passwd を 直接フィールド分割して変数 u に read している。
- 問題2: ユーザの抽出
-
/etc/passwd から、次を調べて下さい。
ログインシェルが bash のユーザと sh のユーザどちらが多い?
1IFS=: 2while read id p u g e d shell 3do 4 case ${shell} in 5 */sh ) 6 sh=$((${sh} + 1));; 7 */bash ) 8 bash=$((${bash} + 1));; 9 esac 10done < /etc/passwd 11echo "bash: " ${bash} 12echo "sh: " ${sh}
問題:1 同様に IFS を : に変更して /etc/passwd を直接フィールド分割して 変数 u、shell に read し、 変数 sh と bash に出現回数をカウントしている。
- 問題5: FizzBuzz
-
1,2,3,4,5…と数えていって…
- 3 の倍数だったら数字の代わりに「Fizz」
- 5 の倍数だったら数字の代わりに「Buzz」
- 15 の倍数だったら数字の代わりに「FizzBuzz」
1i=1 2while [ ${i} -lt ${1:-100} ] 3do 4 if [ $((${i} % 15)) -eq 0 ] 5 then 6 echo -n "FizzBuzz," 7 elif [ $((${i} % 5)) -eq 0 ] 8 then 9 echo -n "Buzz," 10 elif [ $((${i} % 3)) -eq 0 ] 11 then 12 echo -n "Fizz," 13 else 14 echo -n "${i}," 15 fi 16 i=$((${i} + 1)) 17done 18echo
素直に 1 から $1 (指定されていない場合は 100) までを $((…)) にて % 演算子で剰余計算して出力している
- 問題8: CPU 使用率
-
top の出力からどのユーザが
何% CPU を使用しているか集計して下さい。
1exec 3<&0 0<< EOF 2`ps aux` 3EOF 4 5while read u p c other 6do 7 if [ "${u}" != "USER" ] 8 then 9 case ${users} in 10 *${u}* ) 11 ;; 12 * ) 13 users="${users} ${u}" 14 ;; 15 esac 16 eval "$u=\$((\$$u + ${c%%.*}))" 17 fi 18done 19 20for i in ${users} 21do 22 echo "${i} : `eval echo '$'$i`" 23done
CPU 使用率は小数点以下切り捨てで計算している。
出現したユーザID を users 変数に格納しておく。
eval と $((…)) を利用して、 ユーザID を変数名とした変数に CPU 利用率を集計している。
最後に for ループで users に格納された ユーザID とユーザIDを変数名とした変数に格納されている 集計値を表示している。
FreeBSD では top -b -n 1 が利用不可なので ps aux の出力を集計する
全てのスクリプトは FreeBSD 上の /bin/sh で動作確認済み。
手元に Linux 環境が存在しないので Linux での動作は未確認だけど、
posix 機能だけしか使用していない(筈)なので Linux でも動作すると思う。