コマンドプロンプトの cd
コマンドって使いづらいですよね?
Linux で一般的な POSIX シェルの cd
とは違い、以下のような欠点があります。
-
cd
だけでホームディレクトリに移動できない。 -
cd -
で前のディレクトリに戻れない。 - 環境変数
PWD
とOLDPWD
がない。(これは別に無くてもいいけど) - ドライブの移動には
/D
オプションを使用する必要がある。
そこでバッチファイルで cd
コマンドのラッパーを作ってなんとかしてみました。
@echo off
if "%OLDPWD%" == "" set OLDPWD=%USERPROFILE%
if "%PWD%" == "" (
for /F "usebackq tokens=*" %%d in (`cd`) do set PWD=%%d
)
if "%~1" == "-" if '%1' == '-' goto :BACK
:GO
setlocal
for /F "usebackq tokens=*" %%d in (`cd`) do set OLDPWD=%%d
if "%~1" == "" (
cd /D %USERPROFILE%
) else (
cd /D %*
)
if errorlevel 1 exit /B %ERRORLEVEL%
for /F "usebackq tokens=*" %%d in (`cd`) do set PWD=%%d
endlocal & cd /D %PWD% & set PWD=%PWD% & set OLDPWD=%OLDPWD%
goto :EOF
:BACK
setlocal
cd /D %OLDPWD%
if errorlevel 1 exit /B %ERRORLEVEL%
endlocal & cd /D %OLDPWD% & set PWD=%OLDPWD% & set OLDPWD=%PWD%
このバッチファイルをどこかにおいて、doskey
でエイリアス設定をすれば完成です。潰してしまった cd
コマンドのカレントディレクトリを表示する機能の代わりとして pwd
も用意しています。
doskey cd=shcd.bat $*
doskey pwd=cd
doskey
のエイリアス設定はコマンドプロンプト起動時にバッチファイルを自動実行させると便利です。(参考 コマンドプロンプトの開始時に定型処理を自動実行するには)
以上です。
おまけ
これだけではなんなんで、少しコードの分かりづらい場所の解説を。
for /F "usebackq tokens=*" %%d in (`cd`) do set PWD=%%d
現在のディレクトリ(= cd
コマンドの出力結果)を環境変数 PWD
に入れるコードです。なんと冗長なのでしょうか・・・
if "%~1" == "-" if '%1' == '-' goto :BACK
cd -
は前のディレクトリに戻るが、cd "-"
だとディレクトリ名として扱うようにした(つもり。バグがあるかも)
:GO
setlocal
for /F "usebackq tokens=*" %%d in (`cd`) do set OLDPWD=%%d
略
endlocal & cd /D %PWD% & set PWD=%PWD% & set OLDPWD=%OLDPWD%
環境変数 OLDPWD
を変更していますが、途中のディレクトリ移動でエラーになったときに途中で exit
し、なかったことにするために setlocal
を使用しています。ディレクトリ移動できた場合のみ endlocal
を実行しますが、通常はこれで環境変数の変更(とディレクトリ移動)が元に戻るのですが、同じ行にコードを書くことで endlocal
の外に環境変数を持ち出すことができます。(行の解釈と実行の順番からこのような挙動になるそうです。)
:BACK
略
endlocal & cd /D %OLDPWD% & set PWD=%OLDPWD% & set OLDPWD=%PWD%
ここも似ていますが、ワーク変数を用いること無く二つの変数の中身を入れ替えています。
あとグチですが、バッチファイルはダブルクォートの扱いが面倒ですね。本来の cd
の挙動と同じく、引数をダブルクォートで括っても括らなくても問題なく、またスペースが含まれてるディレクトリであってもちゃんと動くようにしたつもりですが、ちょっとした書き方の違いで変数の中にダブルクォートが含まれたりして大変でした・・・。