読むだけでちょっと賢くなる、架空のまとめスレ

【疑問】ユーザー一覧を1行ずつ処理したい。for・while・read・seq と exec、条件に合ったら root にメール【LPICレベル1】

17レスカテゴリ:Linux
1: 名無しさん

ファイルに並んだユーザー名を1行ずつ読んで処理するスクリプトを書きたい
くり返しはどう書くん?

2: 名無しさん

前提のおさらい。[ ] は test コマンドで、条件が正しければ終了ステータス0。if の条件にはどんなコマンドも書ける

3: 名無しさん

>>1
決まった並びを順に回すなら for
for i in 1 2 3; do …; done
for f in *.sh; do …; done で .sh のファイルを1つずつ
for i in $(seq 3); do …; done で 1 から 3

4: 名無しさん

>>3
seq は数の並びを出すコマンド
seq 3 → 1 2 3
seq 2 5 → 2 3 4 5
seq 1 3 10 → 1 4 7 10(3つずつ)
seq -w 8 10 → 08 09 10(桁をそろえる)
seq -s, 3 → 1,2,3

5: 名無しさん

>>1
1行ずつ読むのは while と read
while IFS=: read name x uid; do echo "$name=$uid"; done < pw
user:x:1000 と root:x:0 の2行のファイルで、user=1000 と root=0 が出た

6: 名無しさん

>>5
read の動きをもう少し
変数が足りないと、残りは最後の変数にまとめて入る。echo "a b c" | { read x y; } で x=a、y=b c
変数を書かないと REPLY に入る
IFS=: で区切りを : に変えられる

7: 名無しさん

>>5
cat pw | while read l; do n=$((n+1)); done にしたら、終わったあと n が0のままやった

8: 名無しさん

>>7
パイプの右側は子のシェルで動くから、中で変えた変数が外に戻らない。done < pw のようにリダイレクトで渡すと、同じシェルで動いて n=2 になった

9: 名無しさん

>>5
条件が成り立つ間は while、成り立つまでは until。until [ $i -ge 2 ] は i が2になったら止まる

10: 名無しさん

>>2
exec って何に使うん?

11: 名無しさん

>>10
2つの使い方がある
exec コマンド 今のシェルをそのコマンドに置き換える。exec echo replaced; echo notreached は replaced だけ出て、後ろは動かへんかった
exec > out.log そのあとの出力を全部ファイルへ。スクリプトの先頭に書くとログを取れる

12: 名無しさん

>>11
置き換えやから PID も変わらへん。echo $$; exec bash -c 'echo $$' で同じ番号が2回出た

13: 名無しさん

>>1
ディスクが一杯に近いときだけ root にメールしたい

14: 名無しさん

>>13
条件で分けて、本文を mail に渡す
if [ "$use" -ge 90 ]; then echo "使用率 $use%" | mail -s "disk warning" root; fi
-s が件名、最後が宛先。何もなければ何も送らない

15: 名無しさん

>>14
mail コマンドは mailutils や bsd-mailx などのパッケージに入ってて、送るには MTA(postfix など)が要る。試した環境には入ってなかったから、ディストリビューションやインストールの内容で使えるかどうかが違う

16: 名無しさん

>>14
use は df --output=pcent / | tail -1 | tr -dc 0-9 みたいにして数字だけ取り出す

17: 名無しさん

>>8
並びは for と seq、行は while read で < から、置き換えとログは exec、知らせるのは if と mail。パイプの右の変数には気をつける

管理人のひとこと