Feb 24, 2011
awk スクリプト
知り合いが awk (1) の勉強をしたいと言ってるので、
支援がてら過去に作成したスクリプトをさらしてみる。
このスクリプトは linux 上で稼働している
あるプログラムが取得した共有メモリの残骸を掃除するスクリプトで、
ipcs (8) で取得した共有メモリ一覧のうち、
3 件連続しているキーが存在する場合 ipcrm (8) をコールして
共有メモリを削除する処理を行う。
短いスクリプトながら、外部コマンドの呼出し (system())、
コマンドからの値取得 (getline())、
そして関数内ローカルスコープの変数定義など
awk (1)の持っている機能を結構活用しているので、
多少なりとも参考にして貰えるとうれしい。
1#!/bin/sh 2# 3# Copyright (c) 2010 Mitzyuki IMAIZUMI, All rights reserved. 4# 5# $Id: shmrm,v 1.7 2010/05/08 09:03:15 mitz Exp $ 6# 7# 共有メモリ削除処理 8# 9 10LANG=C /usr/bin/ipcs -m | sort | 11 12awk ' 13 # 14 # 初期処理 15 # 16 BEGIN{ 17 18 max = 0; # 削除対象キーインデックス 19 num = 0; # 削除対象共有メモリインデックス 20 ipcrm = "/usr/bin/ipcrm"; # ipcrm コマンド 21 22 } 23 24 # 25 # 16進数 -> 10進数変換 26 # cmd, dec はローカル変数として利用するために仮引数宣言とする 27 # 28 function h2d(hex, cmd, dec) 29 { 30 31 # printf(1) を利用して 16進数を 10進数に変換 32 cmd = sprintf("printf '%%d' %s", hex); 33 # printf(1) の実行結果を getline で変数 dec に取得 34 cmd | getline dec; 35 close(cmd); 36 37 return dec; 38 39 } 40 41 # 42 # 3連続するキーかのチェック 43 # start, i はローカル変数として利用するために仮引数宣言とする 44 # 45 function cont3(num, start, i) 46 { 47 48 start = h2d(key[num]); 49 50 for(i=1; i<3; i++) 51 if(h2d(key[num+i]) != start + i) 52 return 0; 53 54 return 1; 55 56 } 57 58 # 59 # コマンド実行 60 # 61 function exec(key, arg) 62 { 63 64 system(sprintf("%s -%s %s", ipcrm, arg, key)); 65 66 } 67 68 # 69 # 共用メモリ/セマフォの削除 70 # 71 function shmrm(key, num) 72 { 73 74 # 共有メモリを削除 75 exec(key, "M"); 76 77 # セマフォを削除 78 if(num % 3 == 2) 79 exec(key, "S"); 80 81 } 82 83 # 84 # メイン処理 85 # 86 { 87 88 # owner が root で権限が 666 かつ nattch が 0 の共用メモリを検索 89 if($3 == "root" && $4 == "666" && $6 == 0) 90 key[max++] = $1; 91 92 } 93 94 # 95 # 終了処理(ある意味こっちがメイン) 96 # 97 END{ 98 99 if("'$1'" == "-f"){ 100 # 強制モード -- 3連続していないキーでも削除 101 for(n in key) 102 shmrm(key[n], 2); 103 } 104 else { 105 # 通常モード -- 3連続しているキーが削除対象なので抽出する 106 for(i=0; i<max; i++) 107 if(cont3(i)) 108 for(j=0; j<3; j++) 109 target[num++] = key[i+j]; 110 111 # 削除対象の共有メモリ/セマフォを削除 112 for(n in target) 113 shmrm(target[n], n); 114 } 115 116 } 117'
Edit this entry...
wikieditish message: Ready to edit this entry.
A quick preview will be rendered here when you click "Preview" button.