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


97

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

my_command `echo Test`

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

my_command Test

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

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


Ответы:


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

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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.