Пакетный эквивалент обратных кавычек Bash

При работе с Bash я могу поместить вывод одной команды в другую команду следующим образом:

my_command `echo Test`

было бы то же самое, что и

my_command Test

(Очевидно, это просто непрактичный пример.)

Мне просто интересно, можете ли вы сделать то же самое в пакетном режиме.


person MiffTheFox    schedule 04.05.2010    source источник
comment
возможный дубликат Как получить результат выполнения команды в переменной в windows?   -  person Cristian Ciupitu    schedule 01.07.2014
comment
Связанный stackoverflow.com/q/434038/6064933   -  person jdhao    schedule 20.02.2021


Ответы (5)


Вы можете сделать это, сначала перенаправив вывод в файл. Например:

echo zz > bla.txt
set /p VV=<bla.txt
echo %VV%
person zvrba    schedule 04.05.2010
comment
Это требует, чтобы вы нашли место, где у вас есть доступ на запись для хранения временного файла; вы должны убирать за собой; этот самый пример позволяет вам читать только самую первую строку ввода. Для всех практических целей вариант for /f намного лучше. - person Joey; 05.05.2010
comment
@grawity - вместе с %random% - person bacar; 26.08.2011
comment
@joey Он читает каждую строку, но как присоединить к аргументу командной строки в single команде. - person user877329; 19.03.2014
comment
как он обрабатывает новые строки? - person andrewrk; 16.10.2017

Вы можете получить аналогичную функциональность, используя скрипты cmd.exe с командой for /f:

for /f "usebackq tokens=*" %%a in (`echo Test`) do my_command %%a

Да, это вроде как неочевидно (мягко говоря), но это то, что есть.

См. for /? для получения подробной информации.

Примечание: я подумал, что для использования «echo» внутри обратных кавычек в команде «for /f» необходимо использовать «cmd.exe /c echo Test», поскольку echo является внутренней командой для cmd.exe, но работает более естественным образом. Пакетные скрипты Windows всегда меня чем-то удивляют (но обычно не в хорошем смысле).

person Michael Burr    schedule 04.05.2010
comment
Что ж, все в этой строке в любом случае выполняется cmd; зачем вам создавать подоболочку для команд, которые уже там совершенно законны? - person Joey; 05.05.2010
comment
@Johannes: Я, кажется, помню ситуации, когда попытка выполнить внутренние команды должна была выполняться, указав cmd.exe или command.com (это может быть какое-то темное воспоминание из дней MS-DOS), но я не помню подробностей - я мог бы даже быть совершенно ошибаюсь. Я был слегка удивлен (но не сильно удивлен), когда echo работал в этом случае без создания cmd.exe. Может быть, меня смущают времена, когда мне приходилось настраивать другие программы для выполнения внутренних команд. Мне, наверное, стоит просто избавиться от записки. - person Michael Burr; 05.05.2010
comment
Обычно это требуется при выполнении встроенных команд оболочки из внешних программ, которые не создают оболочку автоматически. Т.е. C system() был прекрасен, iirc, поскольку он в любом случае запускает оболочку, но Process.Start .NET должен явно вызывать оболочку. Что-то в этом роде, iirc. В любом случае считаю, что это лучший ответ, чем принятый :-) - person Joey; 05.05.2010
comment
Варианты for не мешают, но запутывают проблему. Что насчет этого: for /f %%a in ('"echo Test"') do my_command %%a - person Evan Haas; 01.08.2012
comment
Используйте одиночный% вместо %% при выполнении того же самого в командной строке, а не в пакетном сценарии. - person jsears; 11.02.2014
comment
Кажется, плохо работает с трубопроводом, например, с оператором ›. Но в остальном это круто. Если только это не была проблема% vs %%, которая у меня была. - person Jonathan; 22.04.2014
comment
@Evan: tokens=* важно. В противном случае, если результат команды включает пробелы, выводится только первое слово. Запустите это в командной строке: for /f %a in ('"echo foo bar"') do echo "%a". Он напечатает "foo". - person Dan Dascalescu; 28.11.2014
comment
Также стоит отметить этот ответ, если вы пытаетесь использовать в команде символы трубы и т. Д. - person Steve Chambers; 14.11.2017
comment
Узел, в котором вы также можете сделать обратное: for /f "usebackq delims=" %%a in (`cmd`). - person thdoan; 23.05.2018
comment
@MichaelBurr, ваша интуиция насчет подоболочки близка к правильной. Цикл FOR /f предназначен для запуска дочернего процесса и чтения стандартного вывода из канала. Для внутренней команды, такой как ECHO, в этом случае CMD неявно выполняет ее через cmd.exe /c. В этом можно убедиться, подключив отладчик. - person Eryk Sun; 13.10.2019
comment
$ for /f "usebackq tokens=*" %%a in (`echo Test`) do dir %%a возвращает %%a was unexpected at this time. Как это должно работать? - person nephewtom; 05.05.2020

Прочтите документацию по команде "for": for /?

К сожалению, я не вошел в Windows, чтобы проверить это сам, но я думаю, что что-то вроде этого может примерно соответствовать тому, что вы хотите:

for /F %i in ('echo Test') do my_command %i
person Weeble    schedule 04.05.2010
comment
Если кто-то еще наткнется на это, когда команда выполняется из командного файла (* .bat), обе переменные% i должны иметь двойной знак процента: %% i. - person mgouin; 02.06.2017

Возможно, я лажаю с синтаксисом стандартного метода for /f, но когда я ввожу очень сложную команду, включающую && и | внутри обратных кавычек в пределах for /f, это вызывает проблемы. Возможна небольшая модификация по сравнению с обычными командами произвольной сложности:

SET VV=some_command -many -arguments && another_command -requiring -the-other -command | handling_of_output | more_handling
for /f "usebackq tokens=*" %%a in (`%VV%`) do mycommand %%a

Поместив сначала полную и сложную команду в переменную, а затем поместив ссылку на переменную в предел, а не помещая сложную команду непосредственно в предел цикла for, вы можете избежать проблем с интерпретацией синтаксиса. В настоящее время, если я скопирую точную команду, которую я установил для переменной VV в приведенном выше примере, туда, где она используется, %VV%, это вызовет синтаксические ошибки.

person mtalexan    schedule 28.01.2014
comment
У меня это не сработало, но я обнаружил, что вы можете сделать конвейер непосредственно внутри команды for, если вы экранируете его с помощью символа carat (^): for / f usebackq tokens = * %% a in (`command ^ | command` ) выполните команду %% a - person Heptite; 26.01.2015
comment
Экранирование карты @Heptite не сработало для меня, но окружающая командная строка с двойными кавычками сработала. - person Alexandr Zarubkin; 09.09.2016
comment
@Heptite В моем случае я не знал, какую серию команд мне нужно будет запустить заранее, они были извлечены из файла в одном случае и переданы в другом. При экранировании вам нужно знать, сколько раз экранировать команду, в зависимости от того, через сколько интерпретаторов она будет выполняться, а в моих случаях использования это не было постоянным количеством интерпретаторов. - person mtalexan; 06.12.2017

Вы всегда можете запустить Bash внутри Windows. Я постоянно делаю это с помощью MSYS (гораздо эффективнее, чем Cygwin).

person davr    schedule 04.05.2010
comment
К сожалению, MSYS в настоящее время почти не поддерживается, поэтому для получения обновленной версии bash вам необходимо установить его отдельно. - person Ed Randall; 14.04.2015
comment
BusyBox еще меньше (~ 432 КБ). Но не полный Баш, а только Эш. Получите неофициальный порт Windows здесь: frippery.org/busybox - person Martin; 14.12.2015