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

97

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

my_command `echo Test`

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

my_command Test

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

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

MiffTheFox
источник

Ответы:

53

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

echo zz > bla.txt
set /p VV=<bla.txt
echo %VV%
Зврба
источник
16
Это требует, чтобы вы нашли место, где у вас есть доступ на запись для хранения временного файла; вы должны убирать за собой; этот пример позволяет вам прочитать только самую первую строку ввода. С практической точки зрения for /fвариант намного лучше.
Joey
@grawity - вместе с%random%
bacar
1
@joey Он читает каждую строку, но как объединить аргумент командной строки в одну команду.
user877329
как он обрабатывает новую строку (и)?
andrewrk
103

Вы можете получить аналогичную функциональность, используя скрипты 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 всегда меня чем-то удивляют (но обычно не в хорошем смысле).

Майкл Берр
источник
2
Обычно это требуется при выполнении встроенных команд оболочки из внешних программ, которые не создают оболочку автоматически. Т.е. C system()был в порядке, iirc, поскольку он в любом случае запускает оболочку, но .NET Process.Startдолжен явно вызывать оболочку. Что-то вроде этого, иирк. В любом случае, я считаю, что это лучший ответ, чем принятый :-)
Джоуи
2
Варианты, которые forне навредят, а запутают проблему. А как насчет этого:for /f %%a in ('"echo Test"') do my_command %%a
Эван Хаас
9
Используйте одиночный% вместо %% при выполнении того же самого в командной строке, а не в пакетном сценарии.
jsears
2
Не очень хорошо работает с конвейером, например с оператором ">". Но в остальном это круто. Если только это не было проблемой% vs %%.
Джонатан
3
@ Эван: tokens=*важно. В противном случае, если результат команды включает пробелы, выводится только первое слово. Запустить в командной строке: for /f %a in ('"echo foo bar"') do echo "%a". Он будет напечатан "foo".
Дэн Даскалеску
29

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

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

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

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

Давр
источник
К сожалению, MSYS сейчас почти не обслуживается, чтобы получить обновленную версию bash, вам нужно установить ее отдельно
Эд Рэндалл,
1
BusyBox еще меньше (~ 432 КБ). Но не полный Баш, а только Эш. Получите неофициальный порт Windows здесь: frippery.org/busybox
Мартин,
3

Возможно, я лажаю с синтаксисом стандартного 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%, это вызывает синтаксические ошибки.

мталексан
источник
1
У меня это не сработало, но я обнаружил, что вы можете сделать конвейер прямо внутри команды for, если вы экранируете его с помощью carat (^): for / f "usebackq tokens = *" %% a in (`command ^ | command`) do command %% a
Heptite
Экранирование карты @Heptite не сработало для меня, но окружающая командная строка с двойными кавычками.
Александр Зарубкин
@Heptite В моем случае я не знал, какую серию команд мне нужно будет запустить заранее, они были извлечены из файла в одном случае и переданы в другом. При экранировании вам нужно знать, сколько раз нужно экранировать команду, в зависимости от того, через сколько интерпретаторов она будет выполняться, и в моих случаях использования это не было постоянным количеством интерпретаторов.
mtalexan 06