В cmd.exe, как вы можете получить одну переменную для экранирования команды setlocal? - PullRequest
8 голосов
/ 04 октября 2010

Я часто использую setlocal в cmd.exe, чтобы избежать загрязнения пространства переменных среды временными переменными (и чтобы убедиться, что расширения команд и отложенное расширение активны).

Однако яв недоумении, как это сделать, если я на самом деле хочу, чтобы одна из этих переменных была доступна.

Рассмотрим следующий код, который дает вам конечный компонент текущего каталога (поэтому c:\pax\dir1 даст вам dir1):

        @echo off
    :main
        setlocal enableextensions enabledelayedexpansion
        call :func
        echo.main_folder = %folder%
        endlocal
        goto :eof

    :func
        setlocal enableextensions enabledelayedexpansion
        set temp=%cd%
        set folder=
    :funcloop1
        if not "x%temp:~-1%"=="x\" (
            set folder=!temp:~-1!!folder!
            set temp=!temp:~1,-1!
            goto :funcloop1
        )
        echo.func_folder = %folder%
        endlocal
        goto :eof

Когда я запускаю это, я получаю вывод:

func_folder = dir1
main_folder =

, и вы можете видеть, что переменная %folder% не сохраняется endlocal.Однако, если я исключу setlocal/endlocal из функции, varaible temp загрязнит пространство имен main.

Я знаю, что могу просто использовать set temp= в конце func иэто удалит переменную окружения, но это не покрывает случай, когда я уже использую эту переменную во внешней области видимости (в этом случае она полностью уничтожается).

Есть ли способ в cmd.exeразрешить выбранной группе переменных среды распространяться за пределы области действия, в то же время предотвращая ее влияние на других?Другими словами, можете ли вы иметь как локальные переменные, так и возвращаемые переменные?


Кроме того, не говорите мне, что есть лучший способ получить конечный компонент пути.Это только пример.

На самом деле, вы можете рассказать мне лучший способ, так как было бы неплохо узнать, но он не будет отвечать на мой конкретный вопрос: -)

Ответы [ 3 ]

10 голосов
/ 04 октября 2010

"Решение этой проблемы состоит в том, чтобы воспользоваться тем фактом, что оболочка CMD оценивает переменные построчно - поэтому размещение ENDLOCAL на той же строке, что и операторы SET, дает желаемый результат:"source: ss64.com

Таким образом, изменяя endlocal функции: на этот ...

endlocal & set folder=%folder%

... вы получите желаемое поведение.

3 голосов
/ 04 октября 2010

Для лучшего чтения и форматирования вы можете использовать скобки.

call :func resultVar
echo(%resultVar%
goto :eof

:func 
setlocal
set var=2
(
  endlocal
  if "%1" NEQ "" set "%1=%var%"
  goto :eof
)

Это работает, потому что командный блок будет развернут как одна строка. Парсер раскрывает первые две фазы (процентные переменные и escape-символы) перед выполнением командного блока. Остальные фазы выполняются вовремя (как задержка расширения, вторая фаза расширения по CALL, ...)

0 голосов
/ 08 июля 2013

endlocal && set aaa=%aaa% && set bbb=%bbb% постоянно устанавливает aaa и bbb вне setlocal и сохраняет этот параметр в командной строке для использования другого пакетного файла (например, если был вызван пакетный файл, содержащий setlocal)из другого пакетного файла вызывающий пакетный файл теперь будет иметь новые настройки для aaa и bbb

Благодаря тому, кто объяснил о endlocal && set. Я просмотрел множество веб-сайтов, чтобы получить решение этой прямой задачи.ситуация.

...