13

コンテキストPATH:最後に別のパス''を追加して更新するWindowsバッチスクリプトを呼び出す必要がありますxxxが、:

  • 重複なし(' 'のようなPATHに
    ''を追加する場合は、' 'のように更新する必要があります)xxxaaa;xxx;bbbPATHaaa;bbb;xxx
  • 集計なし
    (''で終わることなくスクリプトを繰り返し呼び出すことができますaaa;bbb;xxx;xxx;xxx;...

私が試したこと:

次の関数は重複を処理し、ジョブを実行します

:cleanAddPath -- remove %~1 from PATH, add it at the end of PATH
SETLOCAL ENABLEDELAYEDEXPANSION
set PATH=!PATH:%~2=!
set PATH=!PATH:;;=;!
set PATH=%PATH%;%~2
set P=!P:;;=;!
echo %PATH%
echo -------------
ENDLOCAL  
exit /b

ただし、遅延拡張ローカルモードが必要です。つまり、スクリプトの最後(またはここでは関数の最後cleanAddPath)で、設定されているものはすべて破棄され%PATH%ます

ユーザー(スクリプトを作成している)にオプションを指定して起動するように依頼することもできますがcmdcmd /V:ON遅延拡張をアクティブにするか、デフォルトでオフにします)、それは実用的ではありません。

上記の方法で変数を変更し、そのスクリプトを呼び出した後もPATH現在のDOSセッションで変数を更新するにはどうすればよいですか?

4

3 に答える 3

8

「 DOS-関数コレクション」のページは、遅延拡張モードを使用している場合でも、関数がDOSで値を返す方法の優れた例を示しています。

次の関数は、必要な変数を追加して更新しますPATH

:cleanAddPath -- remove %~2 from %~1, add it at the end of %~1
SETLOCAL ENABLEDELAYEDEXPANSION
set P=!%~1!
set P=!P:%~2=!
set P=!P:;;=;!
set P=!P!;%~2
set P=!P:;;=;!
(ENDLOCAL & REM.-- RETURN VALUES
  SET "%~1=%P%"
)
exit /b

を使用したパスの連結に注意してください。ジェブ のコメントとして:

set P=%P%;%~2パスにのようにアンパサンドが含まれている場合、この線は重要ですC:\Documents&Settings
「」を設定するように変更することをお勧めしP=!P!;%~2ます。

これは、遅延拡張機能を使用して設定した値をSET "%~1=%P%"(で表される変数に)記憶できる部分です。 私は最初に使用 しましたが、jebコメント%~1
SET "%~1=%P%" !

末尾の感嘆符は、遅延拡張モードで、前に準備した場合にのみ(良好な)効果があるため、コマンドSET "%~1=%P%" !を簡略化できます。SET "%~1=%P%"%P%

変数を更新するには、次のコマンドPATHで関数を呼び出します。

call :cleanAddPath PATH "C:\my\path\to\add"

そして、現在のDOSセッションでは、そのスクリプトを終了した後も存続します。

dbenham回答は、より堅牢な回答(賛成)を示していますが、私の場合、このスクリプトで十分です。

于 2012-08-18T16:16:07.673 に答える
3

問題はあなたが思うほど単純ではありません。ENDLOCALバリアを越えて更新された値を返す必要がある最後に到達する前に、コードを壊す可能性のある問題がいくつかあります。

私は、同様の質問に対して提供した回答の拡張として、この質問にすでに回答しました。ディレクトリが%PATH%に存在するかどうかを確認する方法を参照してください。。その回答では、問題を複雑にする問題の大規模なリストを提供します。
リンクされた回答の下部にあるコードは、パスがまだ存在しない場合にパスを確実に追加する方法を示し、バリアPATHを越えて値を確実に返す方法も示しています。ENDLOCAL

以下の編集は、回答への単なるリンクではなく、実際に回答をここに配置することを目的としたVonCによるものです。編集内容は保持しますが、完全にリンクされた回答のコンテキストなしでフォローするのは難しいと思います。

[答えは、値を確実に返す方法を示しています]set "%~1=%var%" !トリックを使用して(末尾の' !'を使用)

そのスレッドには次のものが含まれます。

それは私にはわかりません。最後の引用符の後ろにある感嘆符は、変数の内容にどのように影響しますか?

遅延拡張の簡単なルールは次のとおり
です。行の各文字について、次のようにします。

  • カレット(^)の場合、次の文字に特別な意味がない場合、カレット自体は削除されます
  • 感嘆符の場合は、次の感嘆符を検索し(ここではキャレットは表示されません)、変数の内容に展開されます
  • このフェーズで感嘆符が見つからない場合、結果は破棄され、代わりに前のフェーズの結果が使用されます(キャレットにとって重要)

したがって、この時点で違いは明らかであるはずです。感嘆符が一列に他の効果を持たない場合でも、キャレットは削除されます。
例:

@echo off
setlocal EnableDelayedExpansion

echo one caret^^
echo none caret^^  !

set "var1=one caret^"
set "var2=none caret^" !

echo !var1!
echo !var2!
----- OUTPUT ----
one caret^
none caret
one caret^
one caret
于 2012-08-18T16:27:41.317 に答える
2

わーい!最後に、これを次のテストコードで機能させました。

@echo off
Setlocal enabledelayedexpansion

Set p="hello world"

( endlocal & rem return

   Set "a1=%p%"

)

Set a1

これは以下を出力します:

a1="hello world"

!を使用せずにテストで遅延拡張を使用した理由は、セットの動作に影響があり、これをテストしているすべてのバッチで遅延拡張が行われているためです。

助けてくれてありがとう:o)

PSローカル環境と外部環境の両方に同じ変数名を使用しようとしましたが、これによりコードが破損しました。したがって、2つの名前が使用されます。

于 2016-03-26T17:06:09.140 に答える