バッチ: データを新しい CMD インスタンスに引数として転送する方法

バッチ: データを新しい CMD インスタンスに引数として転送する方法

別の CMD インスタンスを呼び出して、親インスタンスからそのインスタンスにデータを渡したいと考えています。

変数を使用する一般的な方法は知っていますが、この場合は endlocal とブリッジングがあまりにも不便なので実現可能ではありません (数十の変数を中継する必要があります)。また、必要なすべてのデータを簡単に移植するために一時ファイルを使用することもわかっていますが、これにより不要なフットプリントが残ります。編集: setx も非常にうまく使用できます。

見ている具体的には次のような引数の一般的な使用法に沿ったもの:

test.bat -setvar"variable"="value" -setvar...

私は以前、限界のある方法を1つ見つけました

他のスレッドで、スタートコマンドの最後にコマンドを追加できることが分かりました

start cmd /c call "test.bat" ^& PAUSE

もちろんこれを逆転させることはできる

start cmd /c call PAUSE ^& TIMEOUT 5 ^& PAUSE ^& test.bat

コマンドには "" や、おそらく特殊文字は使用できません。複雑な変数を移植しようとすると問題が発生します。

特殊文字といえば:

start cmd /c call (PAUSE) ^& (TIMEOUT 5) ^& (REM !"#¤%&/=?`´^*"-.,_:;\*~¨) ^& test.bat

これはまったく機能しません。解釈を回避できるかもしれませんが、一部の変数の場合、処理可能な値に処理できるだけの十分な値を知る余裕がない可能性があります。--実際には、括弧は許容されないようです。

私が行う必要がある主なことの 1 つはボリューム名を渡すことですが、これは簡単に実現できますが、それだけでは十分ではありません。

start cmd /c call echo \\?\Volume{6537febd-01bc-11d6-adb5-806e6f6e6963}\ ^& TIMEOUT 5 ^& PAUSE ^& test.bat

これはすでに他の場所で説明されている可能性がありますが、そうである場合、問題は、関連するスレッドに対する適切なキーワードまたは類似点を見つけられなかったことです。

答え1

cmdインスタンス継承する親環境変数からすべての環境変数を取得します。証明: 2 つのバッチ スクリプトを作成しましょう。

テスト1.bat

@setlocal
@set _batch
@set "_batchParentName=%~nx0"
@set "_batchParentPath=%~dp0"
@set "_batchParentSpec=< LSS > GTR & amper | pipe"
start "%~n0" cmd /C call "test.bat" "%_batchParentSpec%" %* ^& pause
@set _batch

テスト.bat

@setlocal
@set _batch
@echo %~n0: %%* = %*

cmdインスタンスの出力:

d:\bat>test1.bat first "1<2" third
Environment variable _batch not defined

d:\bat>start "test1" cmd /C call "test.bat" "< LSS > GTR & amper | pipe" first "1<2" third
 & pause
_batchParentName=test1.bat
_batchParentPath=D:\bat\
_batchParentSpec=< LSS > GTR & amper | pipe

d:\bat>

cmdインスタンスの出力元test.bat:

_batchParentName=test1.bat
_batchParentPath=D:\bat\
_batchParentSpec=< LSS > GTR & amper | pipe
test: %* = "< LSS > GTR & amper | pipe" first "1<2" third
Press any key to continue . . .

右に注意してくださいstartコマンド構文"title"

START "title" [/D path] [options] "command" [parameters]

常に TITLE を含めます。これは、「My Script」のような単純な文字列でも、空の引用符のペアでもかまいません。Microsoft のドキュメントによると、タイトルはオプションですが、選択した他のオプションによっては、省略すると問題が発生する可能性があります。

確保するコマンドstartではないオプションスイッチが含まれています/I( からstart /?):

 /I      The new environment will be the original environment passed
         to the cmd.exe and not the current environment.

子環境の変更による別の不測の事態を排除するには、次のよう/Dにスイッチを追加します。cmd

start "test1" cmd /D /C call "test.bat"

に従ってcmd /?

/D      Disable execution of AutoRun commands from registry

答え2

を使用してsetx、Windows 全体に適用される環境変数を設定できます。

使用するにはsetx、次のように記述するだけです。namesetx "name" "variable"は単純な名前、variable は設定する変数です。

setx /?オプションについてさらに詳しく知りたい場合は、すべてのオプションとパラメータを参照してください。

ただし、setx は変数を現在のユーザーのレジストリ ハイブに直接保存することに注意してください。つまり、管理者権限は必要ありませんが、変数は現在の cmd セッションで直接使用できないことも意味します。set変数をローカルに保存するだけの場合は、通常のコマンドを使用してください。

もちろん、次の例に示すように、ローカル変数をグローバル変数に格納することもできます。

@echo off
:: store "test" in variable "a"
set a=test

:: make this variable global
setx a %a%

上記の例でわかるように、は%a%ローカルスコープ内の変数を参照し、setxはそれをパブリックに利用できるようにします。

グローバル変数を設定解除するには、次のコマンドを呼び出します。setx "name" ""例:setx a ""

また、次の点にも留意してください。別のインスタンスで setx を使用して、cmd の 1 つのインスタンスを変更することはできません。cmd ウィンドウを起動すると、set のみが内部の変数を変更でき、setx は外部に変数を保存できます (終了時に)。

関連情報