Это не прямой ответ на исходный вопрос, который задавался Why doesn't [..] work?
, но этот ответ может быть полезен для людей, ищущих & # x332; c & # x332; h & # x332; i & # x332; e & # x332; v & # X332; е & # X332; что будет логический результат примерно так:
echo:somevalue|set /p somevar=
Обычный обходной путь, например, для кода выше, будет:
echo:somevalue>tempfile.txt&set /p somevar=<tempfile.txt
, которая отлично работает, за исключением того, что создает новый файл, с которым нужно будет разобраться впоследствии (помимо того, что нам нужно предпринять дополнительные шаги, чтобы этот новый файл не перезаписывал существующий, который мы не создавал или никогда не намеревался заменить).
Хотя это правда, никак не может использовать поток файлов для преодоления разрыва по обеим сторонам оператора |
канала в том, что касается переменных среды, находясь в среде Windows NT. и при условии том, на котором находится скрипт, использует файловую систему NTFS, можно использовать что-то гораздо более элегантное, чем временные файлы: альтернативные потоки данных
Давайте рассмотрим пример, иллюстрирующий, как их можно использовать:
echo:somevalue>".\%~nx0":temp&set /p somevar=<".\%~nx0":temp
Здесь %~nx0
обозначает и расширяется до имени файла (базовое имя + расширение) нашего пакетного файла, заключенного в кавычки, если он содержит пробелы.
Примечание:
В то время как можно использовать %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 l_input=@FirewallAPI.dll,-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 для создания символической ссылки на one альтернативный поток данных, который затем предоставит нам стандартное имя файла, которое будет использоваться с обычными командами управления файлами.
- В качестве альтернативы можно использовать один из множества доступных инструментов для управления альтернативными потоками данных, например Streams , LADS или AlternateStreamView .
- Полезная команда для вывода списка обычных файлов , включая альтернативные потоки данных из командной строки:
dir /a-d /r
. Затем вы можете использовать любую программу для доступа к потоку имен (альтернатив) данных файла, например, notepad.exe myscript.cmd:data
Надеюсь, это поможет!