Nano Hash - криптовалюты, майнинг, программирование

Назначьте вывод программы переменной с помощью командного файла MS

Мне нужно назначить вывод программы переменной с помощью командного файла MS.

Итак, в оболочке GNU Bash я бы использовал VAR=$(application arg0 arg1). Мне нужно аналогичное поведение в Windows с использованием командного файла.

Что-то вроде set VAR=application arg0 arg1.



Ответы:


1

Один из способов:

application arg0 arg1 > temp.txt
set /p VAR=<temp.txt

Другой:

for /f %%i in ('application arg0 arg1') do set VAR=%%i

Обратите внимание, что первый % в %%i используется для экранирования % после него и необходим при использовании приведенного выше кода в пакетном файле, а не в командной строке. Представьте, в вашем test.bat есть что-то вроде:

for /f %%i in ('c:\cygwin64\bin\date.exe +"%%Y%%m%%d%%H%%M%%S"') do set datetime=%%i
echo %datetime%
26.02.2010
  • Это отличный трюк, интересно, почему он не работает с трубкой 11.04.2013
  • Это работает только для вывода, который представляет собой одну строку текста (последующие строки опускаются после первого разрыва строки). 08.08.2015
  • @Machta: вертикальная черта должна быть экранирована знаком ^ перед ним внутри выражения в скобках. Пример: for /f "tokens=3" %%i in ('route print ^| findstr "\<0.0.0.0\>"') do set "myVar=%%i" 20.08.2015
  • Не работайте за строку с пробелами. Например: для / f %% i в ('ver') установите VAR = %% i. Как писал @Renat, следует добавить токены = * 13.01.2016
  • Я бы также добавил, что FOR параметры команды (т.е. usebackq и delims) могут очень помочь с сложные / длинные команды, например MediaInfo : for /F "usebackq delims=^" %%i in (`"C:\progra~2\path\mediainfo.exe --Output=General;%%Duration/String3%% %1"`) do set getter=%%i 03.07.2016
  • @GroovyCakes Ответ на ваш вопрос о нескольких строках в выводе дает этот ответ на повторяющийся вопрос. 31.05.2017
  • Что, если я хочу выполнить команду, в которой есть%, например: for / f %% i in ('git log -1 --pretty = format: %% H') установить GIT_COMMIT = %% i 25.01.2019
  • Второй способ быстрее? 23.08.2019

  • 2

    В дополнение к этому предыдущему ответу каналы можно использовать внутри оператора for, экранированного символом вставки:

        for /f "tokens=*" %%i in ('tasklist ^| grep "explorer"') do set VAR=%%i
    
    18.10.2013
  • Два важных момента: используйте жетоны для захвата и каретки, чтобы сбежать из трубы. 29.10.2014
  • Эквивалентная версия, которая работает в интерфейсе командной строки и может быть скопирована для упрощения работы: for /f "tokens=*" %i in ('tasklist ^| findstr explorer') do @echo %i Но в целом usebackq следует использовать для обработки сложных команд. 14.12.2017
  • Токены были необходимы для обработки пробелов в выводе. 23.05.2018
  • Цитаты мне тоже подходят, например: for /f "tokens=*" %%i in ('"tasklist | grep explorer"') do set VAR=%%i. Мне проще, если в самой команде нет кавычек. 23.04.2020

  • 3

    @OP, вы можете использовать для циклов, чтобы фиксировать статус возврата вашей программы, если она что-то выводит кроме чисел

    24.02.2010

    4

    При выполнении: for /f %%i in ('application arg0 arg1') do set VAR=%%i я получал ошибку: %% i было неожиданным в это время. В качестве исправления мне пришлось выполнить указанное выше как for /f %i in ('application arg0 arg1') do set VAR=%i

    07.12.2016
  • В пакетном файле вам нужно %%, а вне пакетного файла в командной строке вам нужно % 25.07.2017

  • 5

    предполагая, что вывод вашего приложения представляет собой числовой код возврата, вы можете сделать следующее

    application arg0 arg1
    set VAR=%errorlevel%
    
    24.02.2010
  • К сожалению, на выходе получается строка. 24.02.2010
  • Ok. Я сохраню это для потомков, но взгляните на ссылку @ jdigital, в которой говорится о передаче вывода во временный файл. 24.02.2010
  • Вывод программы на stdout и stderr отличается от целочисленного возвращаемого значения. Программа может возвращать целочисленное значение, как в приведенном выше примере, а также отправлять строку на консоль (или перенаправлять в файл или в другое место). Они не исключают друг друга и представляют собой два разных понятия. 17.11.2016

  • 6

    Вы можете использовать пакетный макрос для простого захвата выходных данных команд, что немного похоже на поведение оболочки bash.

    Использование макроса простое и выглядит как

    %$set% VAR=application arg1 arg2
    

    И работает даже с трубами

    %$set% allDrives="wmic logicaldisk get name /value | findstr "Name""
    

    Макрос использует переменную как массив и сохраняет каждую строку в отдельном индексе.
    В примере %$set% allDrives="wmic logicaldisk будут созданы следующие переменные:

    allDrives.Len=5
    allDrives.Max=4
    allDrives[0]=Name=C:
    allDrives[1]=Name=D:
    allDrives[2]=Name=F:
    allDrives[3]=Name=G:
    allDrives[4]=Name=Z:
    allDrives=<contains the complete text with line feeds>
    

    Для его использования не важно понимать, как работает сам макрос.

    Полный пример

    @echo off
    setlocal
    
    call :initMacro
    
    %$set% ipOutput="ipconfig"
    call :ShowVariable ipOutput
    echo First line is %ipOutput[0]%
    
    echo( 
    %$set% driveNames="wmic logicaldisk get name /value | findstr "Name""
    call :ShowVariable driveNames
    
    exit /b
    
    :ShowVariable
    setlocal EnableDelayedExpansion
    for /L %%n in (0 1 !%~1.max!) do (
        echo %%n: !%~1[%%n]!
    )
    echo(
    exit /b
    
    :initMacro
    if "!!"=="" (
        echo ERROR: Delayed Expansion must be disabled while defining macros
        (goto) 2>nul
        (goto) 2>nul
    )
    (set LF=^
    %=empty=%
    )
    (set \n=^^^
    %=empty=%
    )
    
    set $set=FOR /L %%N in (1 1 2) dO IF %%N==2 ( %\n%
        setlocal EnableDelayedExpansion                                 %\n%
        for /f "tokens=1,* delims== " %%1 in ("!argv!") do (            %\n%
            endlocal                                                    %\n%
            endlocal                                                    %\n%
            set "%%~1.Len=0"                                            %\n%
            set "%%~1="                                                 %\n%
            if "!!"=="" (                                               %\n%
                %= Used if delayed expansion is enabled =%              %\n%
                    setlocal DisableDelayedExpansion                    %\n%
                    for /F "delims=" %%O in ('"%%~2 | findstr /N ^^"') do ( %\n%
                    if "!!" NEQ "" (                                    %\n%
                        endlocal                                        %\n%
                        )                                               %\n%
                    setlocal DisableDelayedExpansion                    %\n%
                    set "line=%%O"                                      %\n%
                    setlocal EnableDelayedExpansion                     %\n%
                    set pathExt=:                                       %\n%
                    set path=;                                          %\n%
                    set "line=!line:^=^^!"                              %\n%
                    set "line=!line:"=q"^""!"                           %\n%
                    call set "line=%%line:^!=q""^!%%"                   %\n%
                    set "line=!line:q""=^!"                             %\n%
                    set "line="!line:*:=!""                             %\n%
                    for /F %%C in ("!%%~1.Len!") do (                   %\n%
                        FOR /F "delims=" %%L in ("!line!") Do (         %\n%
                            endlocal                                    %\n%
                            endlocal                                    %\n%
                            set "%%~1[%%C]=%%~L" !                      %\n%
                            if %%C == 0 (                               %\n%
                                set "%%~1=%%~L" !                       %\n%
                            ) ELSE (                                    %\n%
                                set "%%~1=!%%~1!!LF!%%~L" !             %\n%
                            )                                           %\n%
                        )                                               %\n%
                        set /a %%~1.Len+=1                              %\n%
                    )                                                   %\n%
                )                                                       %\n%
            ) ELSE (                                                    %\n%
                %= Used if delayed expansion is disabled =%             %\n%
                for /F "delims=" %%O in ('"%%~2 | findstr /N ^^"') do ( %\n%
                    setlocal DisableDelayedExpansion                    %\n%
                    set "line=%%O"                                      %\n%
                    setlocal EnableDelayedExpansion                     %\n%
                    set "line="!line:*:=!""                             %\n%
                    for /F %%C in ("!%%~1.Len!") DO (                   %\n%
                        FOR /F "delims=" %%L in ("!line!") DO (         %\n%
                            endlocal                                    %\n%
                            endlocal                                    %\n%
                            set "%%~1[%%C]=%%~L"                        %\n%
                        )                                               %\n%
                        set /a %%~1.Len+=1                              %\n%
                    )                                                   %\n%
                )                                                       %\n%
            )                                                           %\n%
            set /a %%~1.Max=%%~1.Len-1                                  %\n%
    )                                                                   %\n%
        ) else setlocal DisableDelayedExpansion^&set argv=
    
    goto :eof
    
    29.01.2019

    7

    В дополнение к ответу вы не можете напрямую использовать операторы перенаправления вывода в части set цикла for (например, если вы хотите скрыть вывод stderror от пользователя и предоставить более приятное сообщение об ошибке). Вместо этого вы должны экранировать их с помощью символа вставки (^):

    for /f %%O in ('some-erroring-command 2^> nul') do (echo %%O)
    

    Ссылка: Перенаправить вывод команды в цикл для пакетного сценария

    15.07.2015

    8

    Я написал скрипт, который пингует google.com каждые 5 секунд и записывает результаты с текущим временем. Здесь вы можете найти вывод в переменные commandLineStr (с индексами)

    @echo off
    
    :LOOPSTART
    
    echo %DATE:~0% %TIME:~0,8% >> Pingtest.log
    
    SETLOCAL ENABLEDELAYEDEXPANSION
    SET scriptCount=1
    FOR /F "tokens=* USEBACKQ" %%F IN (`ping google.com -n 1`) DO (
      SET commandLineStr!scriptCount!=%%F
      SET /a scriptCount=!scriptCount!+1
    )
    @ECHO %commandLineStr1% >> PingTest.log
    @ECHO %commandLineStr2% >> PingTest.log
    ENDLOCAL
    
    timeout 5 > nul
    
    GOTO LOOPSTART
    
    02.04.2018

    9

    Некоторые макросы для установки вывода команды в переменную /

    Ибо прямо в командной строке

    c:\>doskey assign=for /f "tokens=1,2 delims=," %a in ("$*") do @for /f "tokens=* delims=" %# in ('"%a"') do @set "%b=%#"
    
    c:\>assign WHOAMI /LOGONID,my-id
    
    c:\>echo %my-id%
    

    Макрос с аргументами

    Поскольку этот макрос принимает аргументы в качестве функции, я думаю, что это самый удобный макрос для использования. в пакетном файле:

    @echo off
    
    ::::: ---- defining the assign macro ---- ::::::::
    setlocal DisableDelayedExpansion
    (set LF=^
    %=EMPTY=%
    )
    set ^"\n=^^^%LF%%LF%^%LF%%LF%^^"
    
    ::set argv=Empty
    set assign=for /L %%n in (1 1 2) do ( %\n%
       if %%n==2 (%\n%
          setlocal enableDelayedExpansion%\n%
          for /F "tokens=1,2 delims=," %%A in ("!argv!") do (%\n%
             for /f "tokens=* delims=" %%# in ('%%~A') do endlocal^&set "%%~B=%%#" %\n%
          ) %\n%
       ) %\n%
    ) ^& set argv=,
    
    ::::: -------- ::::::::
    
    
    :::EXAMPLE
    %assign% "WHOAMI /LOGONID",result
    echo %result%
    

    FOR / F макрос

    не так просто читать, как предыдущий макрос.

    ::::::::::::::::::::::::::::::::::::::::::::::::::
    ;;set "{{=for /f "tokens=* delims=" %%# in ('" &::
    ;;set "--=') do @set ""                        &::
    ;;set "}}==%%#""                               &::
    ::::::::::::::::::::::::::::::::::::::::::::::::::
    
    :: --examples
    
    ::assigning ver output to %win-ver% variable
    %{{% ver %--%win-ver%}}%
    echo 3: %win-ver%
    
    
    ::assigning hostname output to %my-host% variable
    %{{% hostname %--%my-host%}}%
    echo 4: %my-host%
    

    Макрос с использованием временного файла

    Легче читать, это не так медленно, если у вас есть SSD-накопитель, но все же он создает временный файл.

    @echo off
    
    :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    ;;set "[[=>"#" 2>&1&set/p "&set "]]==<# & del /q # >nul 2>&1" &::
    :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    
    chcp %[[%code-page%]]%
    echo ~~%code-page%~~
    
    whoami %[[%its-me%]]%
    echo ##%its-me%##
    
    09.11.2020

    10
  • (плюс1) для объяснения обратных кавычек 09.10.2019
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..