
Я только что понял, что запускаю bat-файл в начале этого раздела реестра, в котором есть echo running abc
и некоторые другие не имеющие отношения к делу вещи
HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\AutoRun
Итак, я изменил этот bat-файл. Это всего лишь одна строка, в ней нет ничего несущественного.
вы видите содержимое bat-файла.
Вот некоторые выходные данные из командной строки, показывающие текущую ситуацию, которая является той же фундаментальной проблемой, но вы должны быть в состоянии воспроизвести проблему.
Теперь вопрос в том,
- Почему написано echo sss, а не echo sss ttt?
- Как мне подавить запуск cmd или этого файла инициализации bat с помощью FOR? Оператор FOR на самом деле должен просто отображать "echo g", а не "echo sss" или "echo sss ttt".
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.
sss ttt
C:\Documents and Settings\Administrator>cd\
C:\>type \blah\startfile.bat <ENTER>
@echo sss ttt
C:\>
C:\>for /f %f in ('echo g ^| findstr "g"') do echo %f <ENTER>
C:\>echo sss
sss
C:\>echo g
g
C:\>
решение1
Почему написано echo sss, а не echo sss ttt?
Поскольку строка sss ttt
содержит пробел, for
команда токенизирует ее и сохраняет первую половину sss
в переменной %f
, а вторую половину ttt
в %g
переменной.
Как мне подавить запуск cmd или этого файла инициализации bat с помощью FOR? Оператор FOR на самом деле должен просто отображать "echo g", а не "echo sss" или "echo sss ttt".
Похоже, для оценки echo g ^| findstr "g"
инициализируется новый интерпретатор команд, а ваш \blah\startfile.bat
автоматически выполняется. Сделайте так, чтобы ваш пакет ничего не выводил.
решение2
Если вы собираетесь использовать его %f
в пакетном файле, вам нужно экранировать его другим %
:
for /f %%f in ('echo g ^| findstr "g"') do echo %%f
Добавьте это в свой пакетный файл, и вы получите желаемый результат.
решение3
Хочу немного расширить ответ Властимила...
КогдаFOR
команда выполняет"echo g"
и перенаправляет вывод вfindstr
,ДЛЯдолжен сначала запустить новый командный процессор, что вызывает\blah\startfile.bat
быть казненным.
\blah\startfile.batвыводит строку, содержащуюsss ttt
. Эта строка обрабатываетсяДЛЯи являетсяНЕТпереданоfindstr.
Согласно справке дляДЛЯ:
Обработка состоит из ..., разбиения на отдельные строки текста и последующего разбора каждой строки на ноль или более токенов. Затем вызывается тело цикла for со значением(ями) переменной, установленным на найденную строку(и) токенов. По умолчанию /F передает первый пустой отделенный токен из каждой строки...
Разделители по умолчанию дляДЛЯявляются:" ,;"(пробел, запятая и точка с запятой).
Первая строка, котораяДЛЯпроцессы содержат строку:ссс ттт. Эта строка содержит" "
(пробел), который является разделителем по умолчанию дляДЛЯ, который анализирует строку и назначает первую строку токена:"сссс"к"%ф". Итак"эхо %f"выводит строку, содержащую только:"сссс". Это первая строка, которую вы видите напечатанной."ттт"просто отбрасывается, потому что"ДЛЯ ... эхо %f"команда не указала, что необходимо включить что-либо, кроме первого токена.
ЕслиДЛЯкоманда была написана по-другому, вы бы увидели полную строку"ссс ттт"повторил.
Вот 3 способаДЛЯДля этого можно было бы написать команду.
Первый способ, с использованием"delims="
опция, устанавливает разделитель дляДЛЯ"пустой", так чтоДЛЯвозвращает всю строку как 1 токен. Токены все еще анализируются, и все разделители (" ,;") удаляются, затем все токены снова объединяются с пробелом между каждым токеном. Это объединенное значение возвращается в переменной"%ф"
C:\>for /f "delims=" %f in ('echo sss ttt') do echo %f
C:\>echo sss ttt
sss ttt
C:\>for /f "delims=" %f in ('echo mm;nn,oo, ;ss ,, tt') do echo %f
C:\>echo mm nn oo ss tt
mm nn oo ss tt
Следующий способ, с использованием"tokens=*"
вариант, рассказываетДЛЯпоместить все найденные токены в значение указанной переменной ("%ф"). Токены по-прежнему анализируются, и все разделители удаляются, затем все токены снова объединяются с пробелом между каждым токеном.
C:\>for /f "tokens=*" %f in ('echo sss ttt') do echo %f
C:\>echo sss ttt
sss ttt
C:\>for /f "tokens=*" %f in ('echo mm;nn,oo, ;ss ,, tt') do echo %f
C:\Users\1-kevin>echo mm nn oo ss tt
mm nn oo ss tt
Этот третий способ, с использованием"tokens=1,*"
вариант, рассказываетДЛЯпоместить первый (1) найденный токен в значение указанной переменной ("%ф"). Оставшиеся токены анализируются, и все разделители удаляются, затем все оставшиеся токены снова объединяются с пробелом между каждым токеном, и это объединенное значение возвращается в переменной, названной буквой, которая следует за указанным именем переменной (так, в этом случае переменная"%г").
C:\>for /f "tokens=1,*" %f in ('echo sss ttt') do echo %f %g
C:\>echo sss ttt
sss ttt
C:\>for /f "tokens=1,*" %f in ('echo mm;nn,oo, ;ss ,, tt') do echo "%f" "%g"
C:\>echo "mm" "nn oo ss tt"
"mm" "nn oo ss tt"
Обратите внимание, что следующее не будет работать, поскольку для переменных, выходящих за пределы указанной переменной, не определены «токены»"%ф":
C:\>for /f %f in ('echo sss ttt') do echo %f %g
C:\>echo sss %g
sss %g
Итак, в вашем примере, если вы добавили"delims="
вариант, вы увидите это:
C:\>for /f "delims=" %f in ('echo g ^| findstr "g"') do echo %f
C:\>echo sss ttt
sss ttt
C:\>echo g
g
C:\>