Это не прямой ответ на исходный вопрос, который просил Why doesn't [..] work?
, но этот ответ может быть полезным для людей, следящих к ̲ с ̲ ч ̲ я ̲ х ̲ v ̲ х ̲ что будет логическим результатом что-то вроде этого:
echo:somevalue|set /p somevar=
нормальный обходной путь, например, для кода выше, будет:
echo:somevalue>tempfile.txt&set /p somevar=<tempfile.txt
, который отлично работает, за исключением того, что он создает новый файл, который должен быть рассмотрен впоследствии (помимо того, что нам нужно предпринять дополнительные шаги, чтобы убедиться, что этот новый файл не перезаписывает существующий мы не создавали или никогда не собирались заменять).
Хотя это правда, нет никакого способа вокруг, используя файловый поток, чтобы преодолеть разрыв через обе стороны от трубы |
оператора, насколько переменные среды обеспокоены тем, находясь под среде Windows NT, и при условии объем скрипт находится на использует файловую систему NTFS, можно использовать что-то более изящное, чем временные файлы: прыжок alternate data streams
Давайте прямо в пример, иллюстрирующий, как можно было бы использовать их:
echo:somevalue>".\%~nx0":temp&set /p somevar=<".\%~nx0":temp
Здесь %~nx0
обозначает, и получает расширение, filename (базовое имя + расширение) нашего командного файла, заключенного в кавычки, в случае, если оно содержит пробелы.
Примечание: Хотя можно было бы использовать %0
непосредственно (без кавычек), а не ссылаться на текущий сценарий, .\%~nx0
более управляемым, если вы когда-нибудь нужно взгляд на расширенном значении команды во время отладки ваш сценарий, , особенно если полный путь к вашему сценарию довольно длинный.
Таким образом, ".\%~nx0":temp
относится к альтернативному потоку данных (ADS) нашего собственным сценария с именем temp
, например myscript.cmd:temp
, что мы создаем (или перезапись) с выводом команды echo
. Поскольку ADS ведут себя так же, как поток по умолчанию файла, команды echo
и set
не видят разницы.
Полный скрипт, использующий метод может выглядеть следующим образом:
@echo off
set __self=".\%~nx0"
set __adsname=test.dat
:: Using some input...
set [email protected],-23000
echo:Input: %l_input%
echo:
:: ...we process it...
expand_str_res_id.exe %l_input%>%__self%:%__adsname%&set /p l_output=< %__self%:%__adsname%
:: ...and show the output, e.g. "File and Printer Sharing"
echo:Output: %l_output%
echo:
:cleanup
set l_input=
set l_output=
type nul> %__self%:%__adsname%
set __self=
set __adsname=
pause
Здесь, в конце сценария, линии type nul> %__self%:%__adsname
, которая может быть расширена на что-то вроде type nul> ".\myscript.cmd":test.dat
, используется для очистки содержимого альтернативного потока данных, который мы только что использовали. Хотя это устанавливает размер альтернативного потока данных в ноль, он делает не стереть его (см. Примечания ниже).
Некоторые заключительные замечания:
Большинство команд не могут понять или работать с альтернативными потоками данных, если они предусмотрены в качестве исходных файлов. Это означает, что следующие не могут быть использованы:
type
, например. type myscript.cmd:data > myscript_data.txt
copy
, например. copy myscript.cmd:data myscript_data.txt
move
, например. move myscript.cmd:data myscript_data.txt
del
/erase
, например. del myscript.cmd:data
ren
/rename
, например. ren myscript.cmd:data myscript.cmd:data.txt
- и так далее
На самом деле, это действительно только Перенаправление файл, который поддерживает альтернативные потоки данных с одним исключением (что я могу думать): команда start
.
- Хотя можно довольно легко очистить/удалить содержимое альтернативного потока данных, удаляемого один довольно хитрый, так как копирование файла или переименования не предполагают какие-либо потоков (ну
:$DATA
из них), а также редактирования/изменения содержимое файла влияет только на поток данных по умолчанию. Тем не менее, у нас есть несколько вариантов, в зависимости от того, что мы пытаемся достичь:
- Если у нас есть только один альтернативный поток данных или не против удаления все из них сразу, а содержание файла - это только текст, тогда мы можем создать новый файл, сохранив только поток данных по умолчанию исходного файла, используя следующую команду
type myscript.cmd > myscript_clean.cmd
, после чего исходный файл можно удалить.
- Если у нас есть права администратора на объеме и работать под Windows Vista или более поздней версии операционной системы, мы можем использовать MKLINK создать символическую ссылку на один альтернативный поток данных, который будет предоставлять нам с стандартное имя файла, которое будет использоваться с обычными командами управления файлами.
- В качестве альтернативы можно использовать один из многих инструментов, доступных для управления чередующимися потоками данных, например Streams, LADS или AlternateStreamView.
- Полезные в список обычных файлов включая альтернативные потоки данных из командной строки
dir /a-d /r
. Затем вы можете использовать любую программу для доступа к потоку данных имен (альтернативных) файла, например. notepad.exe myscript.cmd:data
Надеюсь, это поможет!
По совпадению, мне нужно было взять номер из одной программы, выполнить некоторую математику, а затем передать ее другому для использования. Это, похоже, делает трюк: echo 5 | (set/P TmpVar = && set/a TmpVar/2)> C: \ test.txt – TonyM
+1; В действительности проблема связана с тем, как Windows реализует трубы. См. [Почему задержка с расширением заканчивается, если внутри блок кода кода?] (Http://stackoverflow.com/q/8192318/1012053), чтобы получить полное объяснение механизма, а также множество интересных побочных эффектов. – dbenham