Пакетний еквівалент зворотних позначок Bash


97

Під час роботи з Bash я можу помістити вивід однієї команди в іншу команду приблизно так:

my_command `echo Test`

було б те саме, що

my_command Test

(Очевидно, це лише непрактичний приклад.)

Мені просто цікаво, чи можете ви зробити те саме в Batch.


Відповіді:


53

Ви можете зробити це, перенаправивши вихідні дані у файл. Наприклад:

echo zz > bla.txt
set /p VV=<bla.txt
echo %VV%

16
Це вимагає від вас знайти місце, де у вас є доступ до запису для зберігання тимчасового файлу; вам доведеться прибирати за собою; цей самий приклад дає змогу прочитати лише перший рядок вводу. З усіх практичних цілей for /fваріант набагато кращий.
Джої,

@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 /?подробиці про кров.

Sidenote: Я думав, що для використання " echo" зворотних позначок у команді " for /f" потрібно буде використовувати " cmd.exe /c echo Test", оскільки echoце внутрішня команда cmd.exe, але це працює більш природним чином. Пакетні сценарії Windows завжди мене якось дивують (але, як правило, не в хорошому сенсі).


2
Зазвичай це доводиться робити під час виконання вбудованих оболонок із зовнішніх програм, які не створюють оболонку автоматично. Тобто C system()було добре, iirc, оскільки він запускає оболонку в будь-якому випадку, але .NET Process.Startповинен явно викликати оболонку. Щось подібне, iirc. У будь-якому випадку, я вважаю, що це краща відповідь, ніж прийнята :-)
Джої,

2
Варіанти forне зашкодити, а заплутати проблему. Що з цим:for /f %%a in ('"echo Test"') do my_command %%a
Еван Хаас

9
Використовуйте один% замість %%, виконуючи те саме в командному рядку, а не в пакетному сценарії.
jsears

2
Здається, це не працює добре з трубопроводами, наприклад, оператор ">". Але інакше це приголомшливо. Хіба що це була лише проблема%% %%, яку я мав.
Джонатан,

3
@Evan: 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

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, якщо уникнути цього з використанням карата (^): for / f "usebackq tokens = *" %% a in (`command ^ | command`) do command %% a
Heptite

Втеча картки @Heptite для мене не спрацювала, але оточуючий командний рядок із подвійними лапками.
Олександр Зарубкін

@Heptite. У моєму випадку я не знав серії команд, які мені потрібно було виконати заздалегідь, вони були витягнуті з файлу в одному випадку, а передані в іншому. З екрануванням потрібно знати, скільки разів виходити з команди, виходячи зі того, скільки інтерпретаторів вона буде виконана, а в моїх випадках використання це не була однакова кількість інтерпретаторів.
mtalexan
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.