コマンド プロンプトを使う


Windows 2000/XP でコマンド プロンプトを起動し、 Ruby スクリプトを実行できるまでを説明します。コマンド プロンプトの詳細は Windows ヘルプや下記サイトを参照してください。
Windows 2000 コマンドライン徹底活用
http://www.atmarkit.co.jp/fwin2k/serial/index/inde...
%WINDIR%\help\ntcmds.chm
Windows XP に付属するコマンド ライン リファレンス。

ステップ


いくつかのステップに分けて説明します。
  • コマンド プロンプトを起動する。
  • Ruby を起動する。
  • 環境設定バッチファイルを作る。
  • ショートカットを作成する。
  • Ruby スクリプトを実行する。

コマンド プロンプトを起動する


次のような画面が表示されるまでを説明します。画面は Windows 2000 のコマンド プロンプト起動直後です。



まずウインドウズ・キーを押しながらRキーを押し、「ファイル名を指定して実行」ダイアログを表示します。名前欄に「%comspec%」と入力し、OKボタンを押します。



エラーが表示される場合は「%comspec%」を「command」や「cmd」に変えてください。

Ruby を起動する


コマンド プロンプトから次のように入力し改行キーを押してください。
ruby -v

Ruby が起動できる状態であればこのように表示されます。バージョンやリリース日、プラットフォームは異なるかもしれません。
ruby 1.8.2 (2004-12-25) [i386-mswin32]

起動できるなら「 Ruby スクリプトを実行する」へ進んでください。

失敗すると、このように表示されます。
'ruby' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。

エクスプローラで Ruby をインストールしたフォルダの bin フォルダに移動します。 ruby.exe をコマンド プロンプト・ウインドウにドラッグ&ドロップします。コマンド プロンプト・ウインドウに移り、半角スペースに続けて「-v」と入力し改行キーを押します。 Ruby を c:\ruby にインストールしたのであれば、文字列は次のようになります。
c:\ruby\bin\ruby.exe -v

改行キーを押し、起動します。
ruby 1.8.2 (2004-12-25) [i386-mswin32]

このように表示されればOKです。

環境設定バッチファイルを作る


上で試したように毎回ドラッグ&ドロップ作業を行うのは大変です。なので、環境設定して簡略できるようにします。

メモ帳などを開き、次のように書き込みます。メモ帳はコマンド プロンプトから notepad コマンドで起動できます。
set RUBY_HOME=< Ruby をインストールしたフォルダ>
set PATH=%RUBY_HOME%\bin;%PATH%

< Ruby をインストールしたフォルダ>は Ruby をインストールしたフォルダのフルパスに置き換えてください。フルパスとはドライブレターを含むパスです。具体的には c:\ruby のようなかたちです。ここにインストールしたのであれば次のようになります。
set RUBY_HOME=c:\ruby
set PATH=%RUBY_HOME%\bin;%PATH%

ファイル名 ruby-env.bat で保存します。保存場所はどこでもかまいませんが、分かりやすいように Ruby をインストールしたフォルダに保存します。

コマンド プロンプトから ruby-env.bat を実行してみます。エラーになる場合はファイルの記述を見直してください。

エラーが表示されなければ Ruby を起動してみます。
ruby -v

起動できなければ次を試します。
%RUBY_HOME%\bin\ruby.exe

これで起動できるのであれば、ruby-env.bat の「set PATH=」行の記述が間違っています。起動できなければ、「set RUBY_HOME=」行が間違っています。

ショートカットを作成する


環境設定バッチファイルを自動実行しコマンド プロンプトを起動するショートカットを作成します。

エクスプローラから ruby-env.bat をドラッグし、デスクトップ上で Alt キーを押しながらドロップします。「ruby-env.bat へのショートカット」というファイルが作成されます。

「ruby-env.bat へのショートカット」アイコンの上で右クリックし、メニューから「プロパティ」を選択します。

「リンク先」欄の先頭に「%comspec% /k 」を挿入します。

「OK」ボタンを押します。

Ruby スクリプトを実行する


メモ帳などで次のスクリプトを記述し、 helloWorld.rb のファイル名で保存します。
puts "Hellow World!"

実行してみます。
ruby helloWorld.rb

このように表示されれば成功です。
Hellow World!

エラーになるときは helloWorld.rb のフルパスを記述します。
ruby: No such file or directory -- helloWorld.rb (LoadError)

helloWorld.rb を c:\temp に保存したのであれば次のようになります。
ruby c:\temp\helloWorld.rb

すっきりしない解説


中級以上のユーザーに向けて情報提供する wiki に初心者向けの情報を載せるのは、おかしくないか? と悩みながら。

環境変数


コマンド プロンプトでは文字入力が多くなるため、タイプ量とタイプミスを減らすため環境変数を使います。環境変数とは先に出てきた %comspec% や %RUBY_HOME% 、%PATH% のことです。パーセント(%)で英数字を括って指定します。

コマンド プロンプトから set と入力し改行キーを押してみます。ずらりと文字列が表示されると思います。登録済みの環境変数と値の一覧です。 set /? と入力し改行キーを押すと set コマンドの説明が表示されます。

環境変数には重要な意味を持つものがあり、誤って書き換えないよう注意してください。

コマンド プロンプトから書き換えた環境変数はコマンド プロンプトを閉じると変更が破棄されます。新たに登録した環境変数も破棄されます。

コマンド プロンプトからコマンドを起動すると起動したコマンドに現在の環境変数が継承されます。

どうやって ruby.exe を見つけてくるのか?


ruby を実行するとき、コマンド プロンプトはどこから ruby を見つけてくるのでしょうか。

前述のように、 ruby を実行しようとしたとき二つの異なる結果が得られます。ひとつは ruby が実行される場合、もうひとつは実行されない場合です。後者は次のようなメッセージが表示されます。
'ruby' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。

Windows はコマンドを実行しようとするとき、環境変数 PATH の記述を調べます。環境変数 PATH にはセミコロン(;)で区切られたフォルダが記述されています。これらのフォルダを順に検索し、実行すべきコマンドを探します。

フルパスを入力せずに ruby を実行するために ruby-env.bat で環境設定しました。内容を振り返ってみます。
set RUBY_HOME=< Ruby をインストールしたフォルダ>
set PATH=%RUBY_HOME%\bin;%PATH%

set コマンドは環境変数に値を設定します。 Windows が ruby コマンドを探せるように PATH 環境変数に %RUBY_HOME%\bin を追加登録しています。 %RUBY_HOME% は set コマンド実行時に変数の値に置き換えられます。

相対パスとフルパス、ドライブ レター

ruby helloWorld.rb

とタイプして helloWorld.rb が実行できなかったとき、 helloWorld.rb のフルパスを指定しました。ファイルは固有のアドレスを持ち、固有のアドレスをフルパスと呼んでいます。

一方、フルパスではない上記のような記述でも実行できます。ドライブレターとルート(後述します)を含まないアドレスを相対パスと呼びます。

相対パスは現在のフォルダから見た相対的なアドレスを指します。現在のフォルダはカレント フォルダと呼びます。

ためしにカレント フォルダを変えてみましょう。コマンド プロンプトを起動した直後は c:\winnt\system32 がカレント フォルダになっています( Windows 2000 の場合)。
cd "c:\program files"

半角スペースを含むパスはダブルクオート(")で括ります。

cd コマンドはカレント フォルダを変更します。「指定されたパスが見つかりません。」などのエラーが表示されなければカレント フォルダが変わっています。 dir コマンドを実行してみましょう。 Common Files などのファイル一覧が表示されます。

今度は別ドライブに移動してみます。 D ドライブが存在し、ドライブ直下に temp フォルダがあるものとします。
cd d:\temp

dir コマンドを実行してみます。 C:\Program Files のファイル一覧が表示されます。

コマンド プロンプトはドライブごとにカレント フォルダを記憶しています。そのためカレント ドライブという概念を持っています。ドライブを変更するには、半角英字1文字のドライブ名に続けてコロン(:)をタイプし、改行キーを押します。
d:

この半角英字1文字のドライブ名とコロンをあわせてドライブ レターと呼びます。

カレント フォルダはドライブごとに設定されます。 dir c: を実行してみてください。 C:\Program Files のファイル一覧が表示されます。

ドライブごとにフォルダー ルートがあります。 c: のルートは c:\、 d: のルートは d:\ です。ドライブ レターに続くバックスラッシュ(\, 日本語環境では円記号)で示されるフォルダー ルートはとても重要です。ドライブ レターと(フォルダー ルートのない)パスの組み合わせは、対象ドライブのカレント フォルダーからの相対パスになります。

カレント ドライブとカレント フォルダを同時に変更する場合は cd コマンドに /d スイッチを付けて実行します。スイッチはフォルダ名の前につける必要があります。たとえば、
cd /d "c:\program files"

コマンドを調べる


Windows ヘルプに詳細が記述されています。また、コマンド プロンプトから help コマンドを実行するとコマンド一覧が表示されます。各コマンドの詳細は、コマンドに半角スペースに続けて /? スイッチをつけて実行すると表示されます。たとえば set コマンドの詳細を調べるには、 set /? と入力し改行キーを押します。

関連付け


拡張子 rb に ruby.exe を関連付け、コマンド プロンプトから rb ファイルを直接実行できるようにします。この作業には管理者権限が必要です。危険をともなうため注意深く作業してください。危険を理解できていないならこの方法を試してはいけません。

まず現在の関連付けのバックアップをとります。コマンド プロンプトから次のコマンドを実行します。カレント フォルダに2つのファイル(assoc.list.<年月日時分>.txt, ftype.list.<年月日時分>.txt)が作成されます。<年月日時分>はバックアップを行った年月日時分の数値です。2007年6月9日12時ちょうどであれば 200706091200 にします。
assoc > assoc.list.<年月日時分>.txt
ftype > ftype.list.<年月日時分>.txt

誤って削除/変更しないよう attrib +r で読み取り専用属性を設定しておきます。
attrib +r assoc.list.<年月日時分>.txt
attrib +r ftype.list.<年月日時分>.txt

別時点での違いを比較するには fc コマンドを使います。

拡張子 rb とファイルタイプ RubyScriptFile が既に作成されている場合、以降の作業で設定を上書きしてしまいます。まず両者が作成されていないことを確認します。
assoc .rb
ftype RubyScriptFile

次のように表示されれば設定は作成されていません。
拡張子 .rb のファイルの関連付けが見つかりません
ファイル タイプ 'RubyScriptFile' が見つからないか、オープン コマンドが関連付けられていません。

では、関連付けの作成を行います。ここからの作業は危険を伴います。充分に注意してください。

管理者権限で次のコマンドを実行します。 %RUBY_HOME% は前述した環境変数です。 ftype で環境変数が展開されない場合は %RUBY_HOME% 環境変数の設定値に置き換えて ftype を実行してください。
assoc .rb=RubyScriptFile
ftype RubyScriptFile="%RUBY_HOME%\bin\ruby.exe" "%1" %*

コマンド プロンプトから実行できるように、拡張子 rb を環境変数 PATHEXT に登録します。必要なときだけ実行可能にするにはコマンド プロンプト起動時に次のコマンドを実行します。
set PATHEXT=.RB;%PATHEXT%

永続的に実行可能にするには Windows の PATHEXT 環境変数を設定します。この方法は当該ユーザ/全ユーザそれぞれに適用できます。全ユーザに適用するには管理者権限が必要です。

XP の場合はスタートメニュー -> コントロールパネル -> システム -> 詳細設定タブ -> 環境変数ボタンでダイアログを開き、ユーザー環境変数もしくはシステム環境変数を設定します。前者は当該ユーザのみ、後者は全ユーザに適用されます。

当該ユーザに設定する場合はユーザー環境変数に新しく PATHEXT 環境変数を追加します。設定値はシステム環境変数の PATHEXT から拝借し拡張子を追加します。

全ユーザに設定する場合はシステム環境変数の PATHEXT 環境変数を編集します。

PATHEXT 環境変数の初期値は次のようになっていると思います。実際の作業にはシステムに登録された値を使用してください。
.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH

行頭に拡張子 rb を追加します。拡張子の頭にピリオド(.)をつけます。区切りはセミコロン(;)です。大文字小文字は区別されません。例では他の設定に倣って大文字で登録しています。
.RB;.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH

コマンド プロンプトを開き、前述した helloWorld.rb を実行してみてください。スクリプトの拡張子は省略して実行できます。

特殊記号



コマンド プロンプトではアンパサンド(&)、パイプ(|)、大なり(>)、小なり(<)、開閉丸括弧( () )を特殊記号として扱います。これらの記号を文字として扱う場合はハット(^)によりエスケープします。ハットそのものはハットによりエスケープします。

また、ダブルクオート(")で括ると幾つかの特殊記号が文字として扱われます。アンパサンド(&)、パイプ(|)、開閉丸括弧( () )、ハット(^)、セミコロン(;)、カンマ(,)は文字として扱われます。
echo &
echo ^&
echo ^^
echo abc^
def
echo "&|()^;,"

ダブルクオート(")を引数に与えるには記号の直前にバックスラッシュ(\, 日本語環境では円記号)を置きます。バックスラッシュはバックスラッシュでエスケープします。 JScript のコマンドライン引数にダブルクオートを含めることはできません。

アンパサンド(&)は複数コマンドを1行に並べて実行する場合に使用します。前実行コマンドの結果にかかわらず後続するコマンドが実行されます。

二重アンパサンド(&&)は複数コマンドを1行に並べて実行する場合に使用します。前実行コマンドが正常終了した場合に後続するコマンドが実行されます。

パイプ(|)は前実行コマンドの標準出力を、後続するコマンドの標準入力として渡します。

二重パイプ(||)は複数コマンドを1行に並べて実行する場合に使用します。前実行コマンドが異常終了した場合に後続するコマンドが実行されます。

大なり(>)は標準出力をファイルにリダイレクトします。

二重大なり(>>)は標準出力をファイルの末尾に追加します。

ファイル ハンドルのリダイレクト(>&)は左値を右値にリダイレクトします。 2>&1 とすると標準エラー出力のファイル ハンドル(2)を標準出力のファイル ハンドル(1)にリダイレクトします。 1>&2 とすると標準出力のファイル ハンドル(1)を標準エラー出力のファイル ハンドル(2)にリダイレクトします。

小なり(<)はファイルを標準入力にリダイレクトします。

ファイル ハンドルのリダイレクト(<&)は >& の逆です。右値を左値にリダイレクトします。

開閉丸括弧( () )はコマンドのグループ化/ネストを行います。コマンドのグループ化は、実行前に環境変数が展開されます。この仕様は予期せぬ脆弱性を招く可能性があります。グループ内で環境変数を使用するには set local ENABLEDELAYEDEXPANSION し遅延環境変数( % のかわりに ! で括る)で参照します。

set EVAL=echo DANGEROUS
echo EVAL is %EVAL%
(%EVAL%)

セミコロン(;)およびカンマ(,)はコマンド引数の区切りとして使用します。両者はコマンド プロンプトの標準コマンドの仕様です。標準ではないコマンド、たとえば ruby ではこのように解釈されません。

パーセント(%)は環境変数を参照する場合に使用します。パーセントを文字として扱うには二重(%%)にします。 call を使用しないバッチ ファイルの呼び出しは環境変数を汚染します。

echo 2 & echo 1
echo 2 & echo 1 | sort
( echo 2 & echo 1 ) | sort
REM 下は標準エラー出力
echo STDERR 1>&2
echo STDERR  >&2
REM 下はできない。
REM echo STDOUT  >&1

%COMSPEC% /c "exit 1" && echo done
%COMSPEC% /c "exit 1" || echo fail
%COMSPEC% /c "exit 1" & echo ignore
%COMSPEC% /c "exit 0" || echo fail

dir /ah%HOMEDRIVE%
dir /ah;%HOMEDRIVE%

Percent Signs Stripped from Batch File Text
http://support.microsoft.com/?scid=kb%3Ben-us%3B75...

エクスクラメーション(!)は遅延環境変数を参照する場合に使用します。遅延環境変数を使用するにはコマンド プロンプトを /V:ON オプション付きで起動するか、setlocal ENABLEDELAYEDEXPANSION を使用する、もしくはレジストリーを設定します。詳しくは %COMSPEC% /h でヘルプを参照してください。

コマンドによっては上記にない記号を特殊な意味で解釈します。たとえば attrib コマンドはプラス(+)から始まる引数を特殊なオプションと解釈します。 attrib コマンドにプラスから始まるファイル名を渡すにはファイル名をダブルクオート(")で括ります。

その他

コマンド


title コマンドはコマンド プロンプトのタイトルを設定します。

ピリオド付の echo コマンド(echo.)は改行を出力します。

コマンドの頭にアット(@)を付けるとバッチファイルで行をエコーしなくなります。echo off ですべてのエコーを抑制します。

REM から始まる行はコメント行です。コメント行の環境変数は展開されます。コメント行には REM のほかにコロン(:) が使えます。コロンのあとに半角空白を置きます。コロンから始まる行は goto のラベルですが、このような使い方ができるようです。コロンはカレント ドライブの変更と解釈される場合があるようです。起きやすいのは、開閉丸括弧のなかでコメント行が連続する場合、コマンドをコメントアウトした場合です。

REM %DATE%
REM dir
::: dir
setlocal, endlocal

バッチ ファイルで設定した環境変数はバッチ実行後に破棄されず、実行環境に引き継がれます。環境変数汚染を避けるには setlocal, endlocal を使用します。バッチ ファイルを使用せず手入力で行った場合は無視されます。下記サンプルはバッチ ファイルに保存し実行してください。

set hoge=HOGE
setlocal
set hoge=HEGE
setlocal
set hoge=HAGE
echo local 2: %hoge%
endlocal
echo local 1: %hoge%
endlocal
echo out: %hoge%

setlocal でコマンド プロンプトのオプションを変更できます。オプションはコマンド プロンプトの起動オプションより優先されます。
オプションコマンド プロンプトの起動オプション説明
ENABLEEXTENSIONS/E:ONコマンド拡張機能を有効にします。
DISABLEEXTENSIONS/E:OFFコマンド拡張機能を無効にします。
ENABLEDELAYEDEXPANSION/V:ON遅延環境変数の展開を有効にします。
DISABLEDELAYEDEXPANSION/V:OFF遅延環境変数の展開を無効にします。

call コマンドを使用しないバッチ ファイルの呼び出しは setlocal オプションをリセットするかもしれません。
pushd, popd

pushd, popd コマンドは一時的なカレント フォルダーの移動と復帰を行います。 pushd でフォルダーを指定し、現在のカレント フォルダーの記憶と移動を行います。 popd で復帰します。 pushd は、異なるドライブのフォルダーへ移動できます。拡張機能が有効( %COMSPEC% /E:ON 。通常は ON )であれば、 chdir(cd) コマンドでは指定できない UNC パスを指定できます。この場合はネットワーク ドライブを作成し、移動します

echo current: %CD%
pushd %USERPROFILE%
echo current: %CD%
pushd %APPDATA%
echo current: %CD%
popd
echo current: %CD%
popd

exit /b は自動で popd しません。

popd で復帰先のフォルダーが存在しない場合はカレント フォルダーを変更しません。またエラー コードを返しません。 ERRORLEVEL 動的環境変数に影響を与えません。
goto

goto コマンドはラベルに処理を移動します。ラベルはコロン(:)から始まる行で、行末もしくは半角スペースまでの文字列をラベル名にします。ラベルはインデントできます。英字大文字小文字の違いは無視されます。多重定義ははじめの定義のみ有効で上書きされません。コロンのみ、複数コロンのラベルはラベルとして認識されません。

ラベル :EOF はデフォルトで定義されているラベルです。ファイル末を指しています。

goto :label
echo ignore. :label
:label

goto :indent
echo ignore. :indent
	:indent

goto :bold
echo ignore. :bold
:BOLD

goto :two
echo ignore. :two word
:two word

goto :many
echo ignore. :many
:many
echo visible?
:many

goto :EOF

::: 以下、エラーになりバッチの実行が中断する。
goto :
echo ignore. single colon
:

goto ::
echo ignore. double colon
::

引数


受け取った引数は %1 から %9 までの引数参照で参照できます。9以上の引数は shift コマンドで番号をずらして参照します。 %0 はバッチ ファイルのコマンド名を指しています。 %* はすべての引数を他のコマンドに受け渡す際に使用します。 %* は shift コマンドの影響をうけません。

ダブルクオート(")で括った引数をバッチ ファイルが受け取ると、ダブルクオートが削除されずに処理されます。 if 文などで使用すると動作がおかしくなります。引数展開を %~1 のように記述すれば両端のダブルクオートが削除されます。しかし充分ではなく、 ""quoted string"" のような引数でエラーになり、処理が止まります。この問題は環境変数置換を利用することで回避できます。

rem bat file
call :if
rem args: 
rem result: true
call :ifs
rem args: 
rem result: true
call :if ""
rem args: ""
rem result: false
call :ifs ""
rem args: 
rem result: true
call :if "quoted string"
rem args: "quoted string"
rem result: true false
call :ifs "quoted string"
rem args: quoted string
rem result: false
call :if ""quoted string""
rem args: ""quoted
rem args: string""
rem result: false
rem call :ifs ""quoted string""
rem args: "quoted
rem args: string"
rem result: error
call :ife ""quoted string""
rem args: "quoted
rem args: string"
rem result: false

goto :file_end

:if
if "" == "%1" (
  @echo true
) else (
  @echo false
)
@goto :EOF

:ifs
@rem %~1 - すべての引用句 (") を削除して、%1 を展開します。(call /?
if "" == "%~1" (
  @echo true
) else (
  @echo false
)
@goto :EOF

:ife
@setlocal
@rem %~1 - すべての引用句 (") を削除して、%1 を展開します。(call /?
set arg1=%~1
set arg1=%arg1:"=%
if "" == "%arg1%" (
  @echo true
) else (
  @echo false
)
@endlocal
@goto :EOF

:file_end

環境変数置換


環境変数の展開時に環境変数に含まれる文字列を置き換えることができます。置換構文は %環境変数名:文字列A=文字列B% で、環境変数に含まれる文字列Aを文字列Bに置き換え展開します。文字列Aには前置アスタリスク(*)が使えます。文字列の先頭からアスタリスクに続く文字列を置き換え対象とします。

set ecd=%CD:\=\\%
echo %ecd%
echo %CD:\=\\%
echo %CD%

ほかに cut コマンドのような部分文字列構文がつかえます。

echo %PATH:~10,10%
echo %date:~2%
echo %date:~-2%

環境変数置換でパーセント(%)を含む文字列は扱えません。しかし遅延環境変数を利用することでパーセントを含む文字列を扱えます。

setlocal ENABLEDELAYEDEXPANSION により遅延環境変数を有効にできない場合があります。重要な処理を行う場合は setlocal /h でヘルプを確認してください。

setlocal ENABLEDELAYEDEXPANSION
set filepath=C:\Documents and Settings
set uri=%filepath:\=/%
set uri=!uri: =%%20!
set uri=file:///%uri%
echo URI: %uri%
endlocal

動的環境変数


set /h で他の動的環境変数一覧を確認できます。ユーザーが明示的に同名の環境変数を定義していた場合はユーザー定義の環境変数が参照されます。 set ERRORLEVEL= のように環境変数を削除してから参照してください。
%CD%カレント フォルダ
%CMDCMDLINE%オリジナルのコマンドライン
%DATE%現在の日付。フォーマットは DATE コマンドと同じ
%TIME%現在時刻。フォーマットは TIME コマンドと同じ
%RANDOM%0 から 32767 までの任意の数字
%ERRORLEVEL%現在の ERRORLEVEL (コマンドの終了値)

set RANDOM=
call :set_exit_code %RANDOM%
goto :EOF

:set_exit_code
exit /b %1

コマンド プロンプトの仕様から動的環境変数の参照に制約があります。環境変数の参照( % )は読み込み時に展開されます。遅延環境変数を有効にし、遅延環境変数展開により動的環境変数を参照します。

@echo off
REM 遅延環境変数を使用する。
setlocal ENABLEDELAYEDEXPANSION
for %%a in (%PATHEXT:;= %) do (
  call :sub_
  set ERRORLEVEL=
  echo ERRORLEVEL: %ERRORLEVEL% !ERRORLEVEL! %%a
  echo RANDOM: %RANDOM% !RANDOM! %%a
)
endlocal
goto :EOF

:sub_
exit /b %RANDOM%

ショートカット キー


F2 キーはカーソルから入力文字までをコピーします。

F4 キーはカーソルから入力文字までを削除します。

F7 キーは実行したコマンドのヒストリーを表示します。上下カーソルで選択し、 Enter キーで実行します。左右カーソル キーで選択のみ、 Esc キーでヒストリーを閉じます。

Ctrl+BackSpace で単語を削除します。

Ctrl+V でクリップボードの内容を貼り付けます(Win10)。 Win7 は Alt+Space E P です。

制限

文字数


コマンド プロンプトでは1行に使用できる文字数に制限があります。 NT 4.0 および 2000 では 2047 バイト、 XP 以降は 8191 バイトに制限されています。制限を越えた文字は無視されます。環境変数を展開したあとの、環境変数の値(値だけ? todo)、引数を含むコマンドの呼び出し、それぞれに適用されます。この制限はコマンド プロンプトの仕様です。

コマンド プロンプト (Cmd.exe) のコマンド ライン文字列の制限
http://support.microsoft.com/kb/830473/ja

長いファイル パス


Windows では長いファイル パスの使用が制限されています。およそ 255 バイトに制限されています。 Windows のバージョンによって制限値が異なるようです。

削除できないなどのトラブルが生じた場合は当ページのリンクに記載したリンク先「NTFS ファイル システム上のファイルまたはフォルダを削除できない」を参照してください。長いファイル パスを直接指定するのではなく相対パスで指定すると、ファイルを操作できる場合があります。対象ファイルが保存されているフォルダーへカレント フォルダーを移動し、操作してみてください。

File name too long cannot copy
http://social.technet.microsoft.com/Forums/en-US/w...

ファイル

デバイス ファイル


一部のファイル名は予約されています。予約されている DOS デバイス名は特殊な意味を持ちます。
CON標準入出力
NUL何もないファイル。 /dev/null と同じ

con デバイス ファイルは読み取りには標準入力を、書き込みには標準出力を指します。 nul デバイス ファイルは読み取りにはファイル サイズ 0 のファイル、書き込みには何も記録しないファイルのように振舞います。

※ 標準入力でキーボードから入力する場合のファイルの終わりは ctrl+z です。

デバイス ファイルはドライブとフォルダーを無視します。たとえば c:\temp\con のように指定しても con デバイス ファイルとして振舞います。

予約されている DOS デバイス名のファイルは通常の方法では作成できません。 UNC パスを使うと作成できます。 UNC パスは長いファイル名もあつかえるはずなのですが > 調べて書け自分todo。 \\?\ のかわりに \\.\ も使えます。
set UNCTEST=%temp%\UNCTEST
mkdir %UNCTEST%
dir %UNCTEST%
type nul > %UNCTEST%\nul
dir %UNCTEST%
type nul > \\?\%UNCTEST%\nul
dir %UNCTEST%
del %UNCTEST%\nul
dir %UNCTEST%
del \\?\%UNCTEST%\nul
dir %UNCTEST%
rmdir %UNCTEST%


MS-DOS Device Driver Names Cannot be Used as File Names
http://support.microsoft.com/?scid=kb%3Ben-us%3B74...

8-1. Windowsパス名の落とし穴
http://www.ipa.go.jp/security/awareness/vendor/pro...

NTFS ファイル システム上のファイルまたはフォルダを削除できない
http://support.microsoft.com/kb/320081/ja

代替データ ストリーム


Windows の NTFS パーティションでは代替データ ストリームが使えます。代替データ ストリームは dir /r ( Vista 以降? XP にはない。 Windows 7 には存在する)もしくは Sysinternals の streams コマンドで表示できます。
echo hello > hoge.txt
type hoge.txt
dir hoge.txt:hoge.txt
echo HELLO > hoge.txt:hoge.txt
dir hoge.txt
type hoge.txt:hoge.txt
notepad hoge.txt:hoge.txt
del hoge.txt
notepad hoge.txt:hoge.txt


Practical Guide to Alternative Data Streams in NTFS
http://www.irongeek.com/i.php?page=security/altds

Streams
http://technet.microsoft.com/en-us/sysinternals/bb...

イディオム


バッチ ファイルのファイル名


バッチ ファイルのファイル名は %0 に入っています。 %~f0 でバッチ ファイルのフルパス、 %~dp0 でバッチ ファイルが保存されているフォルダー名を取得できます。記号の意味は call /h のヘルプを参照してください。

STDIN


バッチ ファイルで標準入力からデータを取得することができます。

for /f "delims=" %%a in ('more') do (
  REM 空行は無視される。
  REM 端末入力からの逐次実行はできない。
  echo ^> %%a
)

con デバイス ファイルと標準入力は別扱いです。

echo | (
REM ctrl+z で終了。
copy con
more )

再実行、スキップ、終了


エラーが発生した場合にユーザーに振る舞いを問い合わせる処理です。

@echo off
set ERRORLEVEL=
call :try
echo exitcode: %ERRORLEVEL%
echo done.
goto :EOF


:try
  echo 作業しています。
:try_retry
(
  call :error1
) || (
  echo エラーが発生しました。
  call :confirm_ynq "再実行しますか?"
  REM if ERRORLEVEL 0 は 0 を含む 0 以上で実行される。
  REM if %ERRORLEVEL% eq 0 は環境変数 ERRORLEVEL が定義されていると動作が変わる。
  if ERRORLEVEL 3 ( echo 処理の中止が選択されました。終了します。&& goto :try_cancel )
  if ERRORLEVEL 2 ( echo 処理がキャンセルされました。次に進めます。&& goto :try_cancel )
  if ERRORLEVEL 1 ( echo 再実行します。&& goto :try_retry )
)
:try_cancel
goto :EOF


:error1
exit /b 1
goto :EOF


rem 再実行、スキップ、終了をユーザーに問い合わせる。
rem デフォルトはスキップ。
:confirm_ynq
  setlocal
:confirm_ynq_loop__
  rem 行末に半角空白が付いている。
  set /p confirm__=%~1 [y/N/q] 
  if /i "y" == "%confirm__:~0,1%" (
    rem yes
    exit /b 1
  ) else if /i "n" == "%confirm__:~0,1%" (
    rem no
    exit /b 2
  ) else if /i "q" == "%confirm__:~0,1%" (
    rem quit
    exit /b 3
  ) else (
    goto :confirm_ynq_loop__
  )
  endlocal
  goto :EOF

script


バッチ ファイルにスクリプトを埋め込んで呼び出すイディオムです。記号の意味は call /? や goto /? を参照してください。

バッチ ファイルに埋め込まずに任意のコマンドを実行する簡単な方法は、バッチ ファイルでランチャーを作成し任意のコマンドを実行する方法です。対象のスクリプトと、実行のためのランチャーの2つのファイルを作成することになります。

次のバッチ ファイルは、同じ場所に保存した、拡張子の異なるファイルを任意のコマンドで実行するランチャーの雛形です。

@ECHO OFF
ANYLANG "%~dpn0.ANYEXT" %*
Ruby

Ruby は -x 起動オプションで shebang 行まで読み飛ばします。

Unicode 文字を含むオプションを受け取るには --encoding utf-8 起動オプションを指定する必要があります。このオプションは ruby の起動時、または環境変数 RUBYOPT で指定します。スクリプトの shebang 行に書いても正しく解釈しません。

Ruby 関係は ActiveScriptRuby の bin フォルダにあるバッチ ファイルが参考になります。

@ECHO OFF
ruby --encoding utf-8 -x "%~f0" %*
@GOTO :EOF

#!ruby

puts "hello"

JScript

@if(0)==(0) ECHO OFF
CScript.exe //NoLogo //E:JScript "%~f0" %*
GOTO :EOF
@end

WScript.echo( "hello" );

Node.js

バッチ ファイルの文字コードと Node.js の文字コードの違いに注意してください。 Node.js の既定の文字コードは UTF-8 です。コマンド プロンプトは chcp 65001 することで UTF-8 で表示できるようになります。

下の方法は1行目に REM /* が表示されます。

REM /*
@echo off
node "%~f0" %*
@GOTO :EOF
REM */ = 0 

console.log( "hello" );


こちらは何も表示されない代わりに process.argv0 が使えません。

@echo off
@rem vim: tabstop=4 fileformat=windows fileencoding=utf8 filetype=js
node --eval "argv0 = process.argv[1]; process.argv.shift(); eval( require( 'fs' ).readFileSync( argv0, 'utf8', 'r' ).replace( /(.|[\r\n])+?\/[*] #!node [*]\//m, '' ) );" -- "%~f0" %*
GOTO :EOF

/* #!node */

console.log( "hello" );


上記よりすっきりしているかわりに、環境変数置換の不具合が紛れ込む可能性がある。

@echo off
@rem vim: tabstop=4 fileformat=windows fileencoding=utf8 filetype=js
setlocal
set argv0=%~f0
node --eval "eval( require( 'fs' ).readFileSync( '%argv0:\=/%', 'utf8', 'r' ).replace( /(.|[\r\n])+?\/[*] #!node [*]\//m, '' ) );" %*
endlocal
GOTO :EOF

/* #!node */

console.log( "hello" );

bash

コマンド プロンプトのラベルと bash の引数評価コマンドを利用しています。バッチはヒア ドキュメントの制約を受けるかもしれない。

GNU bash, version 3.1.17(1)-release-(i686-pc-msys) で確認しました。

: <<\EOS
@echo off
bash "%~f0" %*
goto :EOF
EOS

echo "hello"


リンク



[REF] コマンド ライン リファレンス
http://technet.microsoft.com/ja-jp/library/cc77808...

[COA] コマンド シェルの概要
http://technet.microsoft.com/ja-jp/library/cc73743...

[RED] コマンド リダイレクト演算子を使用する
http://technet.microsoft.com/ja-jp/library/cc77262...

[WSP] Windows Script Programming
http://scripting.cocolog-nifty.com/

[NTF] NTFS ファイル システム上のファイルまたはフォルダを削除できない
http://support.microsoft.com/kb/320081/ja

[NAM] Naming Files, Paths, and Namespaces (Windows)
http://msdn.microsoft.com/en-us/library/aa365247(v...

todo


todo

if
for
set /a # 演算
set /p # 入力プロンプト

更新履歴



2020/12/22tue 問い合わせのイディオム、 ruby での Unicode 文字を含む起動オプションの受け取り方を追記した。もろもろ。
2017/10/28sat グループ化の問題を追記した。もろもろ。
2017/4/14fri スクリプト埋め込みイディオムの node.js の不備を修正。
2017/3/5sun スクリプト埋め込みイディオムの node.js に追記。
2017/2/28tue スクリプト埋め込みイディオムに node.js の例を追記。
2016/10/28fri 相対パスとフルパス、ドライブ レターに追記。特殊記号に追記。
2016/2/4thu コマンドに追記。
2016/1/31sun 引数について記述。環境変数置換に追記。
2014/2/18tue 動的環境変数に追記。もろもろ追記。
2013/11/1fri バッチファイルのパイプについて記述。複数コロンによるコメントに追記。
2013/10/29tue pushd, popd について記述。
2013/10/28mon コメント(:)の記述が間違っていたので修正。 setlocal, endlocal, goto について記述。スクリプト埋め込みイディオムに bash の例を追記。環境変数置換に追記。
2013/10/3thu 環境変数置換について記述。長いファイル パスに追記。
2010/12/11sat 制限について記述。
2010/6/3thu デバイス ファイル、代替データ ストリームを追記。特殊記号、イディオムに追記。分かりにくい記述をすこし修正。
2010/3/23tue イディオムを追記。動的環境変数を追記。分かりにくい記述をすこし修正。
2009/1/1thu 特殊記号に追記。キーを記述。
2007/6/9sat 関連付けに追記。
2007/6/9sat 関連付け、特殊記号、その他を追記。
2006/12/17sun cd /d について追記。
2006/12/9sat インストール例のパスに半角スペースが含まれていることに気付く...
2006/1/12thu 重大なミスに気づく |ー ̄;) PATH 環境変数の設定記述が間違ってました。ついでに解説追加。
2005/12/29thu ページ作成。

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

Wiki内検索

編集にはIDが必要です