引数で指定されたプロセスを強制終了する

自動で稼動し続ける何かを運用に乗っけた場合、それを強制終了する手段が必要になるものの、「Ctrl + Cで」とか、「タスクマネージャで」とかはオペレーション上アリエナイので、このスクリプトでショートカットボタンを作って、それをクリックしてもらったり。
そんな使い方なので、終了確認も組み込んであげてみたりしてます。

Set objLocator = WScript.CreateObject("WbemScripting.SWbemLocator")
Set objService = objLocator.ConnectServer
Set objArgs    = Wscript.Arguments

strMsg = objArgs(0) & "を強制終了します。よろしいですか?"
Set objShell   = WScript.CreateObject("WScript.Shell")
rc = objShell.Popup(strMsg, 10,, vbOkCancel)

If rc = vbCancel Then
	Wscript.echo "強制終了はキャンセルされました。"
	Wscript.Quit
ElseIf rc = vbTimeOut Then
	Wscript.echo "タイムアウトにより強制終了はキャンセルされました。"
	Wscript.Quit
ElseIf rc = vbOK Then
	Set colProcSet = objService.ExecQuery("Select * From Win32_Process Where Caption='" & objArgs(0) & "'")
	For Each objProc In colProcSet
		objProc.Terminate
	Next
End If

i = 10
Do
	strTmp = ""
	Set colProcSet = objService.ExecQuery("Select * From Win32_Process Where Caption='" & objArgs(0) & "'")
	For Each objProc In colProcSet
		strTmp = objProc.Name
	Next
	
	If strTmp <> "" Then
		i = i - 1
		If i = 0 Then
			Wscript.echo objArgs(0) & "を終了できませんでした。"
			Wscript.Quit
		End If
		Wscript.Sleep 500
	Else
		Exit Do
	End If
Loop

Wscript.echo objArgs(0) & "を終了しました。"
Wscript.Quit

最初の応答に答えなかった場合は、デフォルトで10秒でタイムアウト→キャンセルされるフェールセーフっぷりなので、適宜延ばすなり、縮めるなり、タイムアウト→実行にしたり変更すると幸せになれる事もあるかも。

全てのファイルの右クリックメニューにエディタを登録する

レジストリエディタで下記のようにキーと文字列を追加する。

[HKEY_CLASSES_ROOT\*\shell\view]
@="SakuraEditor"

[HKEY_CLASSES_ROOT\*\shell\view\command]
@="d:\\tools\\sakura\\sakura.exe \"%1\""

サクラエディタを例にしてますが、もちろん何でも登録可能。
regeditの使い方までは未フォロー :-P

grepの色々

こんなテキストを色々grepしてみる。

$ cat hoge.txt
A  111
B  222
AB 333
a  444

行番号をつける

$ grep -n A hoge.txt
1:A  111
3:AB 333

大文字小文字を無視

$ grep -i A hoge.txt
A  111
AB 333
a  444

AND検索(AかつB)

$ grep A hoge.txt | grep B
AB 333

AND検索(AまたはB)

$ grep -e A -e B hoge.txt
A  111
B  222
AB 333

ただし、Solarisの標準grep(/bin/grep)は低機能版でeオプションが使えない。"/usr/xpg4/bin/grep"は高機能版なのでeオプションが使える。

除外検索(Aを含まないB)

$ grep B hoge.txt | grep -v A
B  222

[warn] (128)Network is unreachable: connect to listener on [::]:80

Solaris10でApache2を使用したら、error_logにこんなメッセージが大量に出力されてた。

[Mon Apr 23 08:48:49 2007] [warn] (128)Network is unreachable: connect to listener on [::]:80

ググれば解るけど、原因はIPv6 を有効にしていて(Solaris10の標準設定)IPv6 のアドレスを設定していないから。まぁ、言われてみりゃ、そらそーだって感じです。
"netstat -an"で見てみれば、確かにIPv6でPort待ち受けしてます。

 TCP: IPv6
  Local Address   Remote Address  Swind Send-Q Rwind Recv-Q  State   If
 --------------- ---------------- ----- ------ ----- ------ ------- ----
  *.*             *.*                 0      0 49152      0 IDLE
  *.22            *.*                 0      0 49152      0 LISTEN
  *.23            *.*                 0      0 49152      0 LISTEN
  *.21            *.*                 0      0 49152      0 LISTEN
  *.80            *.*                 0      0 49152      0 LISTEN

対策としては、Apacheインストール前なら、インストール時にconfigureオプションで"--disable-ipv6"を指定。インストール後ならhttpd.confのListendディレクティブに、Portを待ち受けるIPアドレスを指定するだけ。

Listen 80
 ↓
Listen 192.168.1.1:80

あとはお決まりに"kill -HUP "で設定を再読み込みして、再度"netstat -an"でIPv6のPortがListenしていない事を確認。

ディレクトリ内ファイルを一括リネームするシェルスクリプト

本番作業前に既存ファイルをリネームしておく、なんて時に一つ一つやるのも面倒なので、スクリプトでサックリと。
*.hogeを*.fooにリネーム。

for file in `find ./ -name "*.hoge" -print`
do
    res=`expr $file : "\(.*\).hoge"`
    mv $file $res.foo
done

毎秒コマンドを打ち続けるシェルスクリプト

サーバやネットワーク機器の設定変更を行っている時、ping以外のコマンドを毎秒打って反応を見たい時がある。そんな時に。

while [ 0 = 0 ]; do COMMAND; sleep 1; done

COMMANDに好きなコマンドを入力。lsでもnetstatでも。

指定コマンドを毎分実行し続けるマクロ

システムに手を入れた翌営業日とか、設定変更した後とか、手動監視で毎分ステータスを確認したりしなきゃいけない時がある。そんな時に。(毎日やるなら、ちゃんとperlとかで書いた方が良いですが)
ちなみにTeraTermは"UTF-8 TeraTerm Pro with TTSSH2"のVer4.51で動作確認してますが、当然使用は自己責任で。:-)

;================================================
;	 AutoExecPerMinute v1.0
;	 # 毎分コマンドを実行し続ける。
;	 # 指定時になったら終了。
;================================================

;; [終了時間の指定]
intEndTime   = 9

;; [ ログファイルの指定 ]
;; LOGDIR\PREFIX-YYYYMMDD-HHMMSS.EXTENTION
;; [環境変数"TEMP"にログを保管]
getenv 'TEMP' LOGDIR
strconcat LOGDIR '\'
PREFIX = 'teraterm'
EXTENTION = '.log'
call MyLogging

call MyGetTime
logwrite strTimebuf

;; [コマンド実行ループ]
;; ※変数iを使えば回数制限可能。
;; "i = i - 1"がコメントアウトしてあると無限ループ。
i = 10
while i>0
	if intHourbuf=intEndTime then
		logwrite 'Loop END because a finish time. '#13#10
		;; [終了処理]
		call MyEnding
		end
	endif

	call MyGetTime
	logwrite #13#10
	logwrite strTimebuf
	logwrite #13#10

	call MyCMD1
	intSetMin=intMinbuf
	
	while intMinbuf=intSetMin
		call MyGetTime
		pause 1
	endwhile
;i = i - 1
endwhile
end


;;---------------------------------------------
;; [実行コマンド]
:MyCMD1
sendln 'date'
sendln 'ls'
return

;;---------------------------------------------
;; [システム時刻の取得]
:MyGetTime
gettime strTimebuf
strcopy strTimebuf 1 2 strHourbuf
strcopy strTimebuf 5 1 strMinbuf
str2int intHourbuf strHourbuf
str2int intMinbuf  strMinbuf
return

;;--------------------------------------------
;; [終了処理]
:MyEnding
sendln 'exit'
return

;;---------------------------------------------
;; [システム日付の取得]
:MyLogging
getdate strDate
strcopy strDate 1 4 strYear
strcopy strDate 6 2 strMonth
strcopy strDate 9 2 strDay

;; [システム時刻の取得]
gettime strTime
strcopy strTime 1 2 strHour
strcopy strTime 4 2 strMinute
;strcopy strTime 7 2 strSecond

;; [ログファイル名を組み立てる]
;; (ログファイルの命名規則に合わせて変更してください)
LOGFILE = LOGDIR
strconcat LOGFILE PREFIX
strconcat LOGFILE '-'
strconcat LOGFILE strYear
strconcat LOGFILE strMonth
strconcat LOGFILE strDay
strconcat LOGFILE '-'
strconcat LOGFILE strHour
strconcat LOGFILE strMinute
;strconcat LOGFILE strSecond
strconcat LOGFILE EXTENTION
logopen LOGFILE 0 0
return

ちなみに環境変数"TEMP"のディレクトリが解らない、階層が深くてログファイルを見つけるのが面倒という方は、ファイル名を指定して実行で%temp%と入力するか、エクスプローラのアドレスバーで同様に%temp%とか入力すると、一発でTEMPに行けるので安心。