WindowsのCUIを少し便利に使う

Last-modified: 2014-08-16 (土) 12:41:50 (1887d)

Windowsは、マウスポインタで複数ウインドウを操作することを主とする高度なGUIを備えたOSだ。コマンドラインシェル(cmd.exe)も付属しているが、低機能なためあまり使われることはない。

Linuxなどを使ったことがある方は感じることが多いと思うが、CUIでの操作がGUIより勝っている場合も多々ある。その場合、標準のWindowsだけでは、要求を叶えることができないことが多い。

例えば、あるログから特定行を抽出(grep)したり、連番のファイルをダウンロード(curl)したりなどだ。いずれもGUIのアプリケーションでも実現できると思うが、CUIのコマンド1行でさくっと終わらせたい作業である。

その場合、人によってはcygwin(http://www.cygwin.com/)をWindowsにインストールして使ったり、別のマシンにLinuxを起動しておき、そこにsshやtelnet等でリモートログインしてCUIを使ったり、またはWindows上でLinuxの仮想マシンを起動してそれを操作する、といった方法で対処することが多いと思う。私も、同様の方法で操作していてことは多い。(Microsoftの「Windows Services for UNIX http://technet.microsoft.com/ja-jp/interopmigration/bb380242.aspx といったパッケージもあり、Cygwinのように使えるらしいが使ったことは無い)

ところが、cygwinはできることの割にインストールやメンテナンスが面倒だったり、LinuxのPCを別に用意するのも大変だったりする。仮想マシンの起動は時間がかかりすぎる。したいことの割には、必要な設備がヘビーすぎるのだ。

windowsのコマンドラインツール環境を整備することで、Linuxのコマンドラインシェルに比較的近い操作性を実現できるのではないだろうか。

cmd.exeの起動方法

私がよく使うのは次の2通りの方法だ。

ファイル名を指定して実行

Windowsキー+R とタイプし、「ファイル名を指定して実行」欄に cmd と入力し、エンターを押す。ユーザーのホームをカレントディレクトリとして、cmd.exeが起動する。手順が短く、マウスに触る必要も無く、どのPCでも同じ操作が通用するのが利点だ。画面を見る必要すら無い。

windows-cui_run-command.png

「ここでコマンドプロンプト」のバッチファイル

Windowsエクスプローラの右クリックの「送る」に登録しておき、実行するとそのディレクトリでコマンドプロンプトが起動するようなバッチファイルを作っておく。同様のシェル拡張もあったりするので、それを使っても良いだろう。

@echo off
if "%1" == "" goto ERROR
%~d1
if "%~x1" == "" goto ARG_IS_DIR
:ARG_IS_FILE
set CDCOMMAND=cd %~p1
cmd /K %CDCOMMAND%
goto END
:ARG_IS_DIR
set CDCOMMAND=cd %1
cmd /K %CDCOMMAND%
goto END
:ERROR
echo 引数でパスを渡してください
pause
goto END
:END

コマンドラインアプリを入れるためのディレクトリを作成する

コマンドラインプログラム用のディレクトリを別途用意する。今回は、D:\bin とする。ディレクトリを作成した後、環境変数 Path に追加することで、コマンド実行時のディレクトリ入力を省略できる。

環境変数Pathに追加するには、Vistaの場合はWindowsキー+Pauseを押下し「システム」を表示させ、「システムの詳細設定(A)」→「詳細設定」タブ→「環境変数(N)」ボタン→「システム環境変数(S)」フィールドセット の中に、「Path」があるので、ダブルクリックで編集ダイアログを表示し、末尾に

;D:\bin

を追記する。例えば、全体で以下のようになる。

%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;D:\bin
windows-cui_path.png

ついでに、PATHEXT に ;.LNK を追加しておくと、便利かもしれない。

Windows用の各種コマンドのダウンロード・インストール

有志の方々が公開している。Windows用のコマンドラインアプリをダウンロードしてインストールする。必要なコマンドは大抵そろっている。既存コマンドの別名定義やオプション変更で済む場合は、バッチファイルで代用すると良いだろう。

例: @dir /w/p とだけ書いたファイルを ls.bat としてD:\binに保存すれば、lsコマンド(引数なし)の代わりになる。

下記サイトで実行バイナリをダウンロードし、.exe .dll をD:\binに入れる。

unxutils

http://sourceforge.net/projects/unxutils/

GNU ユーティリティ詰め合わせ。大抵はこれで事足りる。

GnuWin32

http://gnuwin32.sourceforge.net/packages.html

GNU ユーティリティ詰め合わせ

cURL

http://curl.haxx.se/

vim

http://www.vim.org/download.php#pc

Win32 console executable というのが公開されている。

pstools

http://technet.microsoft.com/ja-jp/sysinternals/bb896683(en-us).aspx

Windows用のコマンドラインユーティリティ郡。 各コマンドは、初回起動時に規約のダイアログが出るので注意。

リモートから使う

せっかくのCUIなので、リモートで操作できた方が良い。

Cygwin や Windows Services for UNIX 以外のフリーのSSHだと、FreeSSHd ( http://www.freesshd.com/ )というのが公開されているが、あまり使いやすいものではない。特に日本語の扱いに難がある。

潔く、Telnet を使うことにする。

Vistaでは、デフォルトでは機能が無効となっているため、 コントロールパネル→「プログラムと機能」→「Windowsの機能の有効化または無効化」より、「Telnetサーバー」と、「Telnetクライアント」を有効にする。

これで、Telnetサービスを使うことができる。他人からPCのコントロールを奪われる危険性があるため、使用には十分注意が必要だ。また、パスワードが平文でネットワーク上を流れるため、スニッフィングされる危険性もある。

ただし、オフィスや家庭内LANであれば、Telnetで十分な場合が多い。

Stoneを使って、Telnet over SSL (telnets)

Telnetの平文通信が不安であれば、SSLで暗号化して通信させると良いだろう。 SSL化するには、stunnel ( http://www.stunnel.org/ ) というツールが有名なようだが、今回は stone ( http://www.gcd.org/sengoku/stone/Welcome.ja.html ) というソフトウェアを使わせていただく。

stone をダウンロードし、実行バイナリ stone.exe とSSLのdllを D:\bin にコピーする。

動作テスト

telnetのサービスを起動した状態でcmd.exeを起動し、

stone 127.0.0.1:23 10023

とコマンドを実行(ファイアウォールは空ける)、さらにcmd.exeを起動し、

telnet 127.0.0.1 10023

と実行してみて、正しくポートが転送されているかチェックを行う。 正しく転送が行われている場合、telnetログインが出来るはず。

ssl証明書の作成

OpenSSL のWindows版をダウンロードし、 http://www.gcd.org/sengoku/docs/NikkeiLinux00-09/SSL.ja.html を元にSSL証明書を作成する。

完成した証明書を D:\binに cert というディレクトリを作成し、その中に入れる。 私は、上記サイトで解説されている「/usr/local/ssl/private/www.pem」を「D:\bin\cert\private.pem」として、「/usr/local/ssl/certs/www.pem」を「D:\bin\cert\newcert.pem」として保存した。

telnetsポート起動バッチファイルの作成

stone -z key=%~d0%~p0cert\private.pem -z cert=%~d0%~p0cert\newcert.pem 127.0.0.1:23 992/ssl
pause

と書いたファイルを、stone-telnets.bat などと名前をつけて D:\bin に作成。 実行すると、ポート992でtelnetsを受け付ける。

他マシンからtelnetsに接続する

windowsのtelnetサーバに接続するには、なんだかんだでmicrosoft謹製のtelnetクライアントが一番だ。ただし、このソフト単体ではtelnetsに接続できない(と思う)ので、クライアント側でもstoneでトンネリングする。

stone <宛先アドレス>:992/ssl 10023

とすれば、実行PCの10023ポートに接続した際、宛先アドレスの992ポートにSSLで接続を行う。つまり、このコマンドを実行後、

telnet 127.0.0.1 10023

とすれば、宛先のサーバに接続できる。

サーバ用ポート起動スクリプトを、Windowsのサービスとして登録する

telnetサーバ側で、

stone -M install telnets -z key=D:\bin\cert\private.pem -z cert=D:\bin\cert\newcert.pem 127.0.0.1:23 992/ssl

とコマンドを実行すれば、telnets受付用のstoneをサービスとして起動できる。

stone -M install telnets -z key=%~d0%~p0cert\private.pem -z cert=%~d0%~p0cert\newcert.pem 127.0.0.1:23 992/ssl

クライアント側で、stoneの後に自動的にtelnetを起動するスクリプトを作成する

クライアント側で、いちいちstoneを実行後にtelnetを起動するのが面倒であるなら、バッチファイルなどにしてしまうのが良い。

ただし、64ビット版のVistaの場合は、バッチファイルやWindows Scripting Host からtelnetを起動することはできない。 理由はこちら。 http://d.hatena.ne.jp/xworks/20090125 64bit版のPythonからは実行できるので、Pythonスクリプトを書いてみる。

import os
import time
import thread

SERVER_ADDRESS = "宛先アドレス"
SERVER_PORT    = "992"
LOCAL_PORT     = "10023"
STONE_EXE      = "stone.exe"

def run_stone():
	stoneCommand = STONE_EXE+" "+SERVER_ADDRESS+":"+SERVER_PORT+"/ssl "+LOCAL_PORT
	os.system(stoneCommand)

thread.start_new_thread(run_stone,())

time.sleep(0.5)

telnetCommand = "telnet.exe 127.0.0.1 "+LOCAL_PORT
os.system(telnetCommand)

これを、telnets_なんとか.py などという名前で保存しておけば、ダブルクリックでtelnetsに接続が可能。

PowerShell?と併用する

Windowsで高度なCUIといえば、Windows PowerShell?だろう。Telnet(s)を使えば、リモートからでも操作ができる。有事のことを考えて、ぜひインストールしておきたい。

http://www.microsoft.com/japan/technet/scriptcenter/hubs/msh.mspx

インストールを終了すると、C:\WINDOWS\system32\WindowsPowerShell?\v1.0\powershell.exe が作成される。ショートカットを D:\bin に powershell.lnk という名前で作成しておけば、コマンドラインで

powershell

と打つだけで起動するので便利だ。バッチファイルでも良いだろう。

上記Telnet(s)サーバにログインした後、powershell と打ってpowershellを起動し、

ls c:\windows\system32 |? {$_.Length -ge 5MB}|less

などと打って、動作を確認してみよう。

windows-cui_powershell.png