ラベル cmd の投稿を表示しています。 すべての投稿を表示
ラベル cmd の投稿を表示しています。 すべての投稿を表示

2011年8月15日月曜日

バッチファイルに潜む罠(4) - 改行を含む文字列の Echo その2

サーカムフレックス「^」で改行をエスケープした複数行の文字列の一行目を消そうとして More +1 したら、一行も出力されない。。。

Command Prompt
C:\>type newline.cmd
@Echo Off
Set STR=^

Some string including^

newline.
Setlocal ENABLEDELAYEDEXPANSION
Echo.!STR! | More +1
Endlocal

C:\>newline.cmd


C:\>

ファイルへリダイレクトして確認したら、サーカムフレックス「^」でエスケープした改行は CRLF ではなくて LF。。。

Set 変数 | (command) を使うと……

Command Prompt
C:\>type newline.cmd
@Echo Off
Set STR=^

Some string including^

newline.
Set STR | More +1

C:\>newline.cmd
Some string including
newline.


C:\>

……成功するから、ほかのコマンドにリダイレクトするときは、バッチファイルでも遅延評価を使わないで
Set 変数名 | (command)
がいいみたい。

バッチファイルに潜む罠(3) - 改行を含む文字列の Echo

改行を含んだ文字列を Echo するには、改行をサーカムフレックスで「^」でエスケープすればよくて、

Command Prompt
C:\>echo. Some string including^
More?
More? newline.
 Some string including
newline.

C:\>

Set コマンドもうまくいく。

Command Prompt
C:\>Set STR=Some string including^
More?
More? newline.

C:\>Set STR
STR=Some string including
newline.

C:\>

でも、Set した変数を Echo すると……

Command Prompt
C:\>Echo.%STR%
Some string including

C:\>

1行目しか表示されない。遅延評価じゃないから 1行目しか表示されないのは分かるけど、2行目の newline. がエラーにならないので、デバッグしにくい。

対処

バッチファイルなら遅延評価(!変数!)が使えるけれど……

Command Prompt
C:\>type newline.cmd
@Echo Off
Set STR=Some string including^

newline.
Setlocal ENABLEDELAYEDEXPANSION
Echo.!STR!
Endlocal

C:\>newline.cmd
Some string including
newline.

C:\>

……コマンドプロンプトでは Setlocal が使えない。

とりあえず 1行目に余分な改行を追加して、使うとき More +1 で 1行目を削除でしのぐ。

Command Prompt
C:\>Set STR=^
More?
More? Some string including^
More?
More? newline.

C:\>Set STR | More +1
Some string including
newline.


C:\>

続き

2011年8月14日日曜日

バッチファイルに潜む罠(2) - Call :(label) の出力を他のコマンドにリダイレクトすると失敗する。

ファイルへのリダイレクトは問題ないけど……

Command Prompt
C:\>dir /b *.txt
aaa.txt
bbb.txt
ccc.txt

C:\>type call2file.cmd
@Echo Off

Call :ECHO_ARGS %*> args.log
Exit /B 0

:ECHO_ARGS
For %%i In (%*) Do Echo.%%~i
Exit /B 0

C:\>call2file.cmd *.txt

C:\>type args.log
aaa.txt
bbb.txt
ccc.txt

C:\>

コマンドへリダイレクトすると……

Command Prompt
C:\>type call2cmd.cmd
@Echo Off

Call :ECHO_ARGS %*| More
Exit /B 0

:ECHO_ARGS
For %%i In (%*) Do Echo.%%~i
Exit /B 0

C:\>call2cmd.cmd
バッチ スクリプト外でバッチ ラベルを呼び出すことはできません。


C:\>

失敗。。。

対処

考え中……

バッチファイルに潜む罠(1) - シェルはファイル名展開してくれない。

Command Prompt
C:\>dir /b *.txt
aaa.txt
bbb.txt
ccc.txt

C:\>type expansion.cmd
@Echo.%*

C:\>expansion.cmd *.txt
*.txt

C:\>

対処

For 文のファイル名展開機能を使う

Command Prompt
C:\>type expansion.cmd
@For %%i In (%*) Do @Echo.%%i

C:\>expansion.cmd *.txt
aaa.txt
bbb.txt
ccc.txt

C:\>

2011年8月12日金曜日

バッチファイルで which コマンド

which.cmd
@Echo Off
If "%1"=="" (
  Echo.Usage: %~nx0 COMMAND
  Echo.Write the full path of COMMAND^(s^) to standard output.
  Exit /b 0
)

For %%i In (%PATHEXT%) Do Call :EXIST_THEN_ECHO %1%%i && Exit /b 0
Echo.%~nx0: no %1 in (%PATH%)
Exit /b 1

:EXIST_THEN_ECHO
If Not Exist "%~1\" If Exist "%~1" Echo..\%~1& Exit /b 0
If Not "%~$PATH:1"=="" Echo.%~$PATH:1& Exit /b 0
Exit /b 1

IE8 や Firefox3 などの data スキーマに対応しているブラウザなら

参照

  • help call

修正履歴

  • カレントフォルダを先に確認 (2011.08.15)
    :EXIST_THEN_ECHO
    If Not "%~$PATH:1"=="" Echo.%~$PATH:1& Exit /b 0
    If Not Exist "%~1\" If Exist "%~1" Echo..\%~1& Exit /b 0

    :EXIST_THEN_ECHO
    If Not Exist "%~1\" If Exist "%~1" Echo..\%~1& Exit /b 0
    If Not "%~$PATH:1"=="" Echo.%~$PATH:1& Exit /b 0

指定されたパスがフォルダか否か調べる(コマンドプロンプト/バッチファイル) - その 2

If Exist でパス名の最後に「\」をつける。

Command Prompt
C:\>type nul > file

C:\>mkdir folder

C:\>If Exist folder\ (Echo.Folder.) Else (Echo.Not folder.)
Folder.

C:\>If Exist file\ (Echo.Folder.) Else (Echo.Not folder.)
Not folder.

C:\>

確認

  • Windows XP Professional Service Pack 3

2011年8月11日木曜日

DIR コマンドのエラーメッセージの謎(コマンドプロンプト)

Command Prompt
C:\>dir /b -
ファイルが見つかりません

C:\>dir /b -\
指定されたファイルが見つかりません。

C:\>dir /b " "
ファイル名または拡張子が長すぎます。

C:\>

確認

  • Windows XP Professional Service Pack 3

内部コマンドのリスト(コマンドプロンプト)

コマンドプロンプトの内部コマンドのリストをウェブで探し出せなかったので作ってみる。

help コマンドからコマンドリストを得る。

Command Prompt
C:\>for /F "skip=1 tokens=1*" %i In ('help') Do @If Not "%j"=="" @Echo.%i

そのコマンドを C:\Windows フォルダから探して、なければ表示する。

internal_command.cmd
C:\>Cd \Windows
C:\Windows>For /F "skip=1 tokens=1*" %%i In ('help') Do @If Not "%%j"=="" @Dir /s /b %%i.com %%i.exe > nul 2>&1 || @Echo.%%i %%j
ASSOC ファイル拡張子の関連付けを表示または変更します。
BREAK 拡張 CTRL+C チェックを設定または解除します。
CALL バッチ ファイル中から、別のバッチ ファイルを呼び出します。
CD 現在のディレクトリを表示または変更します。
CHDIR 現在のディレクトリを表示または変更します。
CLS 画面を消去します。
COLOR コンソールの文字と背景の既定の色を設定します。
COPY 1 個以上のファイルを別の場所にコピーします。
DATE 日付を表示または変更します。
DEL 1 個以上のファイルを削除します。
DIR ディレクトリ中のファイルやサブディレクトリの一覧を表示します。
ECHO メッセージの表示、コマンド エコーのオン、オフの指定をします。
ENDLOCAL バッチ ファイルで、環境変数のローカライズを終了します。
ERASE 1 個以上のファイルを削除します。
EXIT CMD.EXE プログラム (コマンド インタープリタ) を終了します。
FOR 指定されたコマンドを、ファイルの集合の各ファイルに対して実行
FTYPE ファイル拡張子の関連付けで使われるファイル タイプを表示または変更
GOTO バッチ ファイル中で、ラベルで定義されている行へ Windows コマンド
IF バッチ ファイル中で、条件処理を実行します。
MD ディレクトリを作成します。
MKDIR ディレクトリを作成します。
MOVE 1 個以上のファイルをディレクトリから別のディレクトリに移動します。
PATH 実行可能ファイルの検索パスを表示または設定します。
PAUSE バッチ ファイルの処理を一時停止し、メッセージを表示します。
POPD 現在のディレクトリを PUSHD で保存したディレクトリに戻します。
PROMPT Windows コマンド プロンプトを変更します。
PUSHD 現在のディレクトリを保存して、変更します。
RD ディレクトリを削除します。
REM バッチ ファイルや CONFIG.SYS の中で、コメント (注釈) を記録します。
REN ファイルの名前を変更します。
RENAME ファイルの名前を変更します。
RMDIR ディレクトリを削除します。
SET Windows 環境変数を表示、設定、または削除します。
SETLOCAL バッチ ファイルで、環境変数のローカライズを開始します。
SHIFT バッチ ファイルで、置き換え可能パラメータの位置をシフトします。
START 別のウィンドウを起動して、指定したプログラムまたはコマンドを実行
TIME システム時刻を表示または変更します。
TITLE コマンド プロンプト ウィンドウのタイトルを設定します。
TYPE テキスト ファイルの内容を表示します。
VER Windows のバージョンを表示します。
VERIFY ファイルがディスクへ正しく書き込まれたかを照合するかどうか
Windows へ指定します。
VOL ディスクのボリューム ラベルとシリアル番号を表示します。

2011年8月4日木曜日

PowerShell メモ

  • コマンドプロンプト(or バッチファイル)からコマンドを指定して実行
    C:\> powershell -Command コマンド群
    ※ クォートやエスケープはいらない。
    ※ 複数のコマンドは ";" で分割
  • コマンドプロンプト(or バッチファイル)からスクリプトを呼び出す
    C:\> powershell -ExcecutionPolicy RemoteSigned -File スクリプト.ps1
  • パスワードを入力させる
    PS> $password = read-host Password -AsSecureString Password: 123456789 PS> $password System.Security.SecureString
    ※ 直接文字列は取得できない
  • [System.Security.SecureString] から文字列を取得する
    PS> $ptr = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($password) PS> [Runtime.InteropServices.Marshal]::PtrToStringBSTR($ptr) 123456789

参照

  • ユーザに文字列を入力させる(1)/(2) - PowerShell Memo
    → http://d.hatena.ne.jp/newpops/20050922/p1
    → http://d.hatena.ne.jp/newpops/20050923/p1

2011年8月2日火曜日

応答があるまで ping を繰り返すバッチファイル

実行方法

  • コマンドプロンプトから引数にホスト名か IP アドレスを指定する。
  • 名前がホスト名か IP アドレスのファイルをバッチファイルにドラッグする。
loop_ping_til_reply.cmd
@Echo Off
Rem (c) http://sofnote.blogspot.com/

Set WAITTIME=60
Set CMDNAME=%~nx0
Set TARGET=%~nx1
If Not "%TARGET%"=="" Goto ARGS_OK
  Echo.Usage:
  Echo.  %CMDNAME% (hostname ^| ip address)
  Echo.or
  Echo.  drag [(hostname ^| ip address)] file icon to [%CMDNAME%] icon.
  Goto ERROR
:ARGS_OK

Rem hostname check
Echo.executing: ping -n 1 %TARGET%...
Set LINES=0
For /F "tokens=*" %%i In ('ping -n 1 %TARGET%') Do Call :PING_ERR_CHECK ".%%i"
  If Not %LINES%==1 Goto HOSTNAME_OK
  Goto ERROR
:HOSTNAME_OK
If %LINES%==9 Goto SUCCESS
ping localhost -n %WAITTIME% > nul

:RETRY
  Echo.executing: ping -n 1 %TARGET%...
  ping  -n 1 %TARGET%
  if Not ERRORLEVEL 1 Goto PINGABLE
  ping localhost -n %WAITTIME% > nul
  Goto RETRY
:PINGABLE


:SUCCESS
Pause
Exit /b 0

:ERROR
Pause
Exit /b 1

Rem Return values:
Rem   LINES: number of line which ping result
:PING_ERR_CHECK
Setlocal ENABLEDELAYEDEXPANSION
  Set MSG=%1
  For /F "tokens=*" %%i In (!MSG!) Do Echo%%~i
Endlocal
Set /A LINES=%LINES%+1
Exit /b 0

IE8 や Firefox3 などの data スキーマに対応しているブラウザなら

2010年7月8日木曜日

コマンドプロンプト(cmd.exe)で、標準出力されたコマンドの結果を変数に格納

linux シェルのコマンド置換をコマンドプロンプトで使いたいときに。。。

注意点

下記コマンド中の ❚(0x08) はコマンド列に含まれない制御文字などであればよくて ❚(0x08) をメモ帳で入力するなら CTRL+BACKSPACE。
※ 詳しくは [参考文献] の [制御コードの入力方法] 項目に記述した文献参照

Set コマンドで COMMAND 変数の内容を設定するときに、エスケープ(^)が必要な文字は 2重にエスケープする。
例えば & を echo させたい場合は ^^^& とする。

コマンド プロンプト
C:\>type stdin2var(1).cmd
@Echo off
Setlocal ENABLEDELAYEDEXPANSION
Set COMMAND=echo ;a b  cd;^^^&echo.""^^^>con:
For /F "usebackq tokens=* eol=❚" %%i IN (`!COMMAND!`) Do Set VAR=%%i
Echo !VAR!
Endlocal

C:\>stdin2var(1).cmd
;a b  cd;&echo."">con:

C:\>

コマンド文字列にダブルクォート(")を含まない場合は下記でもよいらしい。

コマンド プロンプト
C:\>type stdin2var(2).cmd
@Echo OFF
For /F "usebackq tokens=* eol=❚" %%i In (`"echo ;a^^^&echo."`) Do Set VAR=%%i
Echo %VAR%

C:\>stdin2var(2).cmd
;a&echo.

C:\>

確認

  • Windows XP SP3

参考文献

遅延評価を使った For /F 文の問題回避方法

  • Windows Script Programming -「FORコマンドのバグ?」
    http://scripting.cocolog-nifty.com/blog/2007/02/for_daa8.html

制御コードの入力方法

  • Windows Script Programming -「FOR /F の eol について」
    http://scripting.cocolog-nifty.com/blog/2008/02/for_f_eol_2f50.html

2010年4月13日火曜日

コマンドプロンプト(cmd.exe) で [Alt]+[半角/全角] を押しても日本語入力モードに切り替わらない

現象

Notepad や Internet Explorer などのウィンドウアプリケーションは [Alt]+[半角/全角] キーで日本語入力モードに切り替わるけれど、コマンドプロンプトで [Alt]+[半角/全角] キーを押しても日本語入力モードに切り替わらない。

日本語入力モードに切り替わると、通常はコマンドプロンプトの右下隅に日本語入力モードが表示される。

コマンド プロンプト
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\Documents and Settings\Administrator>



全あ連ローマ

原因

解明できず。
conime.exe は起動している。
余計なプロセスがキーコード入力を捕獲してしまっているのかと cmd.exe 拡張プログラムを削除してみたけれど効果なし。

回復した方法

[テキスト サービスと入力言語] 設定画面の [設定] タブにある [既定の言語(L)] を [日本語 - Microsoft Natural Input 2002 ver.8.1] から [日本語 - Microsoft IME Standard 2002 ver.8.1] に変更したら回復。
そのあと [既定の言語(L)] を [日本語 - Microsoft Natural Input 2002 ver.8.1] に戻しても問題なし。

[テキスト サービスと入力言語] 画面までの手順は次のとおり。

  1. [スタート] メニュー
    (- [設定(S)] ※ クラシック [スタート] メニューの場合)
    - [コントロール パネル(C)]
  2. [コントロール パネル] 画面
    (- [日付、時刻、地域と言語のオプション] ※カテゴリ表示の場合)
    - [地域と言語のオプション]
  3. [地域と言語のオプション] 画面
    - [言語] タブ
    - [詳細(D)] ボタン

確認

  • Windows XP SP3

参考

検索できず(2010-04-13)。

2010年4月6日火曜日

regedit.exe のコマンドラインオプション

reg.exe を使えばいいので、特に必要ないかもしれない。

登録エントリファイル(.reg) でレジストリにエントリを追加・変更・削除

regedit [/s] .reg
  • /s - サイレントモード。下記のような確認画面を表示しない。
レジストリ エディタ

? .reg 内の情報をレジストリに追加しますか?

  • はい(Y)
  • いいえ(N)

レジストリからエントリをファイルへ出力

regedit /a filename [regpath] regedit /e filename [regpath]
  • /a - REGEDIT4 形式(Shift-JIS) で出力
  • /e - REGEDIT5 形式(UTF-16LE) で出力

確認できなかったオプション

  • /l - 古いオプションの名残?
  • /r - 古いオプションの名残?

確認

  • Windows XP SP3

2010年3月8日月曜日

シェルスクリプト/バッチファイルで一時停止

シェルスクリプト

bash
$ echo -n "any key for exit"; stty -echo; read -n 1 i; stty echo; echo
any key for exit
$ 

下記 shell で確認

  • bash(sh で起動)
    GNU bash, version 3.2.25(1)-release (i686-redhat-linux-gnu)
  • ksh
    sh (AT&T Research) 93s+ 2008-01-31

バッチファイル

Command Prompt
>pause
続行するには何かキーを押してください . . .

>

下記 shell で確認

  • cmd.exe
    Microsoft Windows XP [Version 5.1.2600]

2010年3月7日日曜日

シェルスクリプト/バッチファイルでフルパス名を分割

シェルスクリプト

フルパス名からファイル名部分を取り出す

bash
$ echo $PWD
/usr/local/lib/firefox-3.6
$ echo ${PWD##*/}
firefox-3.6
$ 

※ 先頭の最長一致部分を削除

フルパス名からディレクトリ名を取り出す

bash
$ echo ${PWD%/*}
/usr/local/lib
$ 

※ 末尾の最短一致部分を削除

下記 shell で確認

  • bash(sh で起動)
    GNU bash, version 3.2.25(1)-release (i686-redhat-linux-gnu)
  • ksh
    sh (AT&T Research) 93s+ 2008-01-31

バッチファイル(cmd.exe)

フルパス名からファイル名部分を取り出す

Command Prompt
>echo %CD%
C:\WINDOWS\system32\drivers\etc
>for %i in ("%CD%") do @echo %~ni%~xi
etc

>

※ ~n:ファイル名(拡張子を除く)
※ ~x:拡張子

フルパス名からディレクトリ名を取り出す

Command Prompt
>for %i in ("%CD%") do @echo %~di%~pi
C:\WINDOWS\system32\drivers\

>

※ ~d:ドライブ名を展開
※ ~p:パス名を展開

下記 shell で確認

  • cmd.exe
    Microsoft Windows XP [Version 5.1.2600]