1

これは私のスクリプトです:

@echo off
setlocal

for /f %%i in ('echo aaa/') do set REPO=%%i
if "%REPO%"=="" (
  echo No input
) else (
  echo %REPO:~-1%
  echo %REPO:~0,-1%
  if %REPO:~-1%==/ set REPO=%REPO:~0,-1%
  echo %REPO%
)

endlocal

観察してください:

c:\dev\shunra\GlobalLibrary\Server>c:\Utils\hgbackup.cmd
/
aaa
aaa/

c:\dev\shunra\GlobalLibrary\Server>

何が起こっている?

編集

「aaa」と評価される何かをREPOに割り当てていることに注意してください。したがって、「aaa /」ではなく「aaa」と出力されることを期待しています。それは私を夢中にさせます。

EDIT2

どうやら、これが犯人です(setコマンドのヘルプから):

Finally, support for delayed environment variable expansion has been
added.  This support is always disabled by default, but may be
enabled/disabled via the /V command line switch to CMD.EXE.  See CMD /?

Delayed environment variable expansion is useful for getting around
the limitations of the current expansion which happens when a line
of text is read, not when it is executed.  The following example
demonstrates the problem with immediate variable expansion:

    set VAR=before
    if "%VAR%" == "before" (
        set VAR=after
        if "%VAR%" == "after" @echo If you see this, it worked
    )

would never display the message, since the %VAR% in BOTH IF statements
is substituted when the first IF statement is read, since it logically
includes the body of the IF, which is a compound statement.  So the
IF inside the compound statement is really comparing "before" with
"after" which will never be equal.  Similarly, the following example
will not work as expected:

    set LIST=
    for %i in (*) do set LIST=%LIST% %i
    echo %LIST%

in that it will NOT build up a list of files in the current directory,
but instead will just set the LIST variable to the last file found.
Again, this is because the %LIST% is expanded just once when the
FOR statement is read, and at that time the LIST variable is empty.
So the actual FOR loop we are executing is:

    for %i in (*) do set LIST= %i

which just keeps setting LIST to the last file found.

Delayed environment variable expansion allows you to use a different
character (the exclamation mark) to expand environment variables at
execution time.  If delayed variable expansion is enabled, the above
examples could be written as follows to work as intended:

    set VAR=before
    if "%VAR%" == "before" (
        set VAR=after
        if "!VAR!" == "after" @echo If you see this, it worked
    )

    set LIST=
    for %i in (*) do set LIST=!LIST! %i
    echo %LIST%

しかし、!記号を使用してみましたが、それでもうまくいきません。!画面に印刷されるか、間違った結果が再び表示されます。

4

3 に答える 3

4

コメントと編集された質問で説明されているように、拡張を遅らせる必要があります。

遅延拡張は、使用する前に有効にする必要があります。バッチスクリプト内で使用できますsetlocal enableDelayedExpansion

@echo off
setlocal enableDelayedExpansion

for /f %%i in ('echo aaa/') do set REPO=%%i
if "%REPO%"=="" (
  echo No input
) else (
  echo %REPO:~-1%
  echo %REPO:~0,-1%
  if %REPO:~-1%==/ set REPO=%REPO:~0,-1%
  echo !REPO!
)

endlocal

編集

REPO が未定義になるように IN() 句が変更された場合、上記は失敗します。例えば:in (echo.)

ELSE 句が実行されなくても、IF/ELSE コンストラクト全体に有効な構文が必要なため、失敗します。

REPO が定義されていない場合、

if %REPO:~-1%==/ set REPO=%REPO:~0,-1%

に展開します

if ~-1REPO:~0,-1

これは無効な構文です。

この問題は、遅延展開を使用することで解決されます。

@echo off
setlocal enableDelayedExpansion

for /f %%i in ('echo.') do set REPO=%%i
if "%REPO%"=="" (
  echo No input
) else (
  echo %REPO:~-1%
  echo %REPO:~0,-1%
  if !REPO:~-1!==/ set REPO=%REPO:~0,-1%
  echo !REPO!
)

endlocal
于 2012-11-03T01:23:13.443 に答える
0

「aaa」と評価されるものをREPOに割り当てていることに注意してください

実際には、条件付きで何かを割り当てています。then-part が実際に実行されているかどうかをテストしましたか (たとえば、echo If Entered)。

于 2012-11-02T21:23:11.793 に答える
0

これは私にとってはうまくいきます(スクリプト全体からの抜粋です)

choice /C 1234567H /M "Select an option or ctrl+C to cancel"
set _dpi=%ERRORLEVEL%

if "%_dpi%" == "8" call :helpme && goto menu 

for /F "tokens=%_dpi%,*" %%1 in ("032 060 064 096 0C8 0FA 12C") do set _dpi=%%1
echo _dpi:%_dpi%:
于 2014-10-30T19:04:18.183 に答える