1 (изменено: wisgest, 2014-02-10 10:54:49)

Тема: CMD/BAT: Определить текущий режим вывода команд

Ещё одна задача по командным файлам: определить (получить в переменную), в каком состоянии (ON или OFF) находится режим вывода команд (ECHO). Желательно, чтобы решение не зависило ни от языка системы, ни от того, в  режиме вывода результатов выполнения команд в каком формате (ANSI — с ключом /A, по умолчанию, или UNICODE — с ключом /U) был запущен обработчик командной строки. Если не сможете найти решение, то поделитесь возникшими соображениями.
Моё решение — в прикреплённом зашифрованном архиве (10.02.2014: удалён за ненадобностью).

2 (изменено: wisgest, 2014-01-06 19:58:41)

Re: CMD/BAT: Определить текущий режим вывода команд

Задачка, по большому счёту, лишь для развлечения. Ну или для прояснения для себя каких-то особенностей работы командных файлов.
Но можно предположить случай, когда командный файл пишется с учётом возможности его использования из других командных файлов и по завершении работы должен вернуть среду в исходное состояние.
Однозначно же утверждать, что вывод команд на экран должен быть отключен нельзя: его можно оставить включенным для отображения критических команд, отключая отображение остальных с помощью «@».

3 (изменено: wisgest, 2014-01-07 07:43:27)

Re: CMD/BAT: Определить текущий режим вывода команд

wisgest пишет:

Ну или для прояснения для себя каких-то особенностей работы командных файлов.

Первым делом неискушённый разработчик может с помощью FOR/F попробовать читать вывод команды ECHO без параметров. Но для исполнения команд таким способом создаётся новый процесс CMD.EXE, на который не распространяются установки родительского процесса:

@echo off
echo
for /f "delims=" %%s in ('echo') do set EchoMode=%%s
echo %EchoMode%

выдаст (в русской версии)

Режим вывода команд на экран (ECHO) отключен.
Режим вывода команд на экран (ECHO) включен.

4

Re: CMD/BAT: Определить текущий режим вывода команд

Как-то так:

(
for /l %%i in (1,1,1) do (
  echo.
))>.txt

for %%i in (.txt) do (
  if %%~zi==2 (
   set echo_is=off
) else (
   set echo_is=on
))
set echo_is
pause>nul

5

Re: CMD/BAT: Определить текущий режим вывода команд

Yury, мысль правильная.
А как насчёт этого:

wisgest пишет:

Желательно, чтобы решение не зависило <...> от того, в  режиме вывода результатов выполнения команд в каком формате (ANSI — с ключом /A, по умолчанию, или UNICODE — с ключом /U) был запущен обработчик командной строки.


cmd /u /c "echo off & test.bat"

6

Re: CMD/BAT: Определить текущий режим вывода команд

wisgest, в том же духе:

(
for /l %%i in (1,1,1) do (
  echo.
))>.txt

for %%i in (.txt) do (
  if %%~zi leq 4 (
   set echo_is=off
) else (
   set echo_is=on
))
set echo_is
pause>nul

7 (изменено: wisgest, 2014-02-10 10:57:09)

Re: CMD/BAT: Определить текущий режим вывода команд

O.K.
Моё решение было такое же, только REM вместо ECHO с точкой
и в итоге сравнение размера файла с нулём.

@(for %%i in (.) do rem
)>x.txt
@for %%f in (x.txt) do @if %%~zf equ 0 (set mode=OFF) else set mode=ON

(Последняя строка — пароль к архиву (10.02.2014: удалён за ненадобностью))

8

Re: CMD/BAT: Определить текущий режим вывода команд

Буржуи тоже интересуются вопросом и решают: http://stackoverflow.com/questions/9592 … cho-status

( 2 * b ) || ! ( 2 * b )

9 (изменено: wisgest, 2014-01-07 15:21:20)

Re: CMD/BAT: Определить текущий режим вывода команд

Rumata пишет:

Буржуи тоже интересуются вопросом и решают

Следует признать, что решение практически идентичное:

:getEchoState echoStateVar
@(
  for %%A in (dummy) do rem
) >"%temp%\getEchoState.tmp"
@for %%A in ("%temp%\getEchoState.tmp") do @(
  if %%~zA equ 0 (set %~1=OFF) else set %~1=ON
  del "%temp%\getEchoState.tmp"
  exit /b
)

--------------------

OFF: Мысль использовать перенаправление вывода FOR...REM мне пришла ранее при решении другой задачи:

wisgest пишет:

получить в общем случае параметры командного файла (в переменную среды, для возможности использования с отложенной подстановкой) без потерь и инъекций кода.

В общих чертах (без подбора допустимого имени временного файла и блокирования от посторонних процессов до его прочтения) решение выглядело так:

prompt .
echo on
@(for %%i in (.) do rem %*
)>args.tmp
@echo off
(set /p=& set /p args=)<args.tmp
set args=!args:~5,-1!
wisgest пишет:

Пожалуй, для этого вопроса лучше создать отдельную тему в разделе отведённом командным файлам.

Тему так и не создал, т.к. в решении разочаровался (хотя, да, с инъекцией кода вопрос решился) по следующим причинам:
1) CMD /U — файл создаётся в юникоде, но SET /P всё-равно читает его как в однобайтной кодировке;
2) CMD /A (как обычно) — в действительности, командная строка может содержать символы в юникоде. Хотя при использовании шрифта Terminal при выводе на экран они заменяются похожими (напр., многоточие на двоеточие), но при внутренней обработке (присваивании параметров командного файла переменным среды, передаче в качестве параметров другим приложениям) они сохраняются. Но при перенаправлении вывода в файл они искажаются;
3) ну и, наконец, CMD /Q.
(Кстати, отсутствие полноценного решения этой задачи я считаю основным и существенным недостатком командных файлов.)

10

Re: CMD/BAT: Определить текущий режим вывода команд

Как дополнение к своему решению обнаружил тот факт, что если к "echo." добавить ">nul", то также можно сравнивать размер файла с нулём:

(
for /l %%i in (1,1,1) do (
  echo.>nul
))>.txt
for %%i in (.txt) do (
  if %%~zi==0 (
   set echo_is=off
) else (
   set echo_is=on
))
set echo_is
pause>nul