26

Re: CMD/BAT: Хитрости и нелепости интерпретатора

Недокументированная возможность команды SETLOCAL

http://stackoverflow.com/a/15659309/3627676 (обсуждение на форуме dostips)
Скрипт с командой setlocal по завершении выполнения возвращается в первоначальный каталог, даже если в скрипте были переходы с помощью команд cd/pushd, но не было возвратов в исходную точку по cd/popd.

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

27

Re: CMD/BAT: Хитрости и нелепости интерпретатора

http://stackoverflow.com/a/26736458/3627676

Создание нового файла нулевого размера.


break >emptyfile.txt

Команда BREAK внутренняя, поэтому выполняется быстро.

Старый способ тоже использует встроенные средства, но он длинее и не такой лаконичный:


set /p "=" <nul >emptyfile.txt
( 2 * b ) || ! ( 2 * b )

28 (изменено: Rumata, 2014-11-08 17:29:26)

Re: CMD/BAT: Хитрости и нелепости интерпретатора

http://stackoverflow.com/a/26717684/3627676

Способ узнать было ли перенаправление на стандарный ввод скрипта


@echo off

timeout /t 0 >nul 2>nul
if %errorlevel% == 1 echo:stdin
if %errorlevel% == 0 echo:normal

Используется особенность программы TIMEOUT, которая не поддерживает перенаправление ввода/вывода. Может потребоваться в случае, если необходимо различить вариант перенаправления


command | script.bat
script.bat < filename

и обычный запуск


script.bat
( 2 * b ) || ! ( 2 * b )

29

Re: CMD/BAT: Хитрости и нелепости интерпретатора

Rumata пишет:

Создание нового файла нулевого размера.

А:

copy nul "file.ext"

— работает в Windows 7 и выше?

30

Re: CMD/BAT: Хитрости и нелепости интерпретатора

copy nul file.ext

работает и в старенькой ХР. Вот только команда может быть и короче:

cd.>file.ext

31 (изменено: Rumata, 2014-11-08 19:14:45)

Re: CMD/BAT: Хитрости и нелепости интерпретатора

Да, кстати, работает.

Вот про copy nul забыл, а про cd. не знал.

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

32

Re: CMD/BAT: Хитрости и нелепости интерпретатора

greg zakharov пишет:

работает и в старенькой ХР.

Про то я знаю, поскольку под ней и сижу . Помнится, вроде как то ли под Windows 8, то ли под Windows Server 2008 R2 не заработало.

33

Re: CMD/BAT: Хитрости и нелепости интерпретатора

alexii пишет:

Про то я знаю, поскольку под ней и сижу

А Вы экстремал

Rumata пишет:

Вот про copy nul забыл, а про cd. не знал.

Странно, что не знали - способ уже замшелый как не знамо что.

34

Re: CMD/BAT: Хитрости и нелепости интерпретатора

greg zakharov пишет:

А Вы экстремал wink

Нищеброд .

35

Re: CMD/BAT: Хитрости и нелепости интерпретатора

"Довесок" к уже упомянутым командам:


@echo off

for %%i in (

 "call"
 "doskey"
 "md nul"
 "sort nul"
 "type nul"

 "echo on"
 "echo off"
 "color"
 "endlocal"
 "setlocal"
 "shift"
 "popd"
 "prompt"
 "set var="
 "title"

 ) do @(
 %%~i>"This empty file was created by using the command ''%%~i''!"
 )

exit /b

.


Первую группу команд, думаю, можно использовать безусловно, а вторую-- в зависимости от ситуации.


К первой группе ещё можно отнести команду "cmd /c".

36

Re: CMD/BAT: Хитрости и нелепости интерпретатора

alexii, тогда как назваться, если WinXP\7 триальные, живут под VirtualBox в Debian?
Yury, способов создания пустого файла много, в ХР, например, можно и через debug, - соль, нужно полагать, здесь не столько в вариативности, сколько в лаконичности.

37 (изменено: Yury, 2014-11-09 11:10:52)

Re: CMD/BAT: Хитрости и нелепости интерпретатора

greg zakharov пишет:

Yury, способов создания пустого файла много, в ХР, например, можно и через debug, - соль, нужно полагать, здесь не столько в вариативности, сколько в лаконичности.


Не совсем так:

Yury пишет:

Первую группу команд, думаю, можно использовать безусловно, а вторую-- в зависимости от ситуации.

То есть, например, если мне нужно почти одновременно применить "SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION" и создать пустой файл, то будет удобнее (и лаконичнее, если хотите) написать:

setlocal enableextensions enabledelayedexpansion>"example.txt"

.

38

Re: CMD/BAT: Хитрости и нелепости интерпретатора

Я бы еще добавил ясность изложения.
Лучше написать так


type nul >filename
copy nul filename >nul

можно и так


call>filename
break>filename

Так как эти команды короче, осмысленнее или отсутствует "сайд-эффекта". Например, cd. трудна для восприятия, нужно задуматься, что тут происходит на самом деле. (хотя break в этом контексте тоже не ахти какая осмысленная команда). setlocal/endlocal лучше оставить для своих прямых обязанностей. В контексте создания пустового файла они выполняют некие дополнительные действия ("сайд-эффект"), а удобство весьма сомнитеьно. В плане лаконичности call лучший кандидат. Это всего лишь мое мнение.

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

39

Re: CMD/BAT: Хитрости и нелепости интерпретатора

Пардон, а где сие

Yury пишет:

setlocal enableextensions enabledelayedexpansion>"example.txt"

применимо? А то мысли всякие нехорошие напрашиваются...

40

Re: CMD/BAT: Хитрости и нелепости интерпретатора

Rumata пишет:

Например, cd. трудна для восприятия...

Ой ли?

41 (изменено: Yury, 2014-11-09 13:06:31)

Re: CMD/BAT: Хитрости и нелепости интерпретатора

greg zakharov пишет:

Пардон, а где сие

Yury пишет:

setlocal enableextensions enabledelayedexpansion>"example.txt"

применимо? А то мысли всякие нехорошие напрашиваются...




@setlocal enableextensions enabledelayedexpansion>"example.txt"

@for %%i in (Мама мыла раму.) do @(
 set x=%%i
 set x=!x:Мама=Папа!
 echo !x:мыла=мыл!>>"example.txt"
 )

@exit /b

Если файл "example.txt" не существует, то он создаётся, если же этот файл существует, то он "опустошается" во избежание дозаписи.



Правда, в этом случае такая необходимость отпадает:


@setlocal enableextensions enabledelayedexpansion

@>"example.txt" (
for %%i in (Мама мыла раму.) do @(
 set x=%%i
 set x=!x:Мама=Папа!
 echo !x:мыла=мыл!
 )
)

@exit /b

.

42

Re: CMD/BAT: Хитрости и нелепости интерпретатора

Yury пишет:

Если файл "example.txt" не существует, то он создаётся, если же этот файл существует, то он "опустошается" во избежание дозаписи.

Простите, но это что-то из области "CMD\BAT: камасутра".

43

Re: CMD/BAT: Хитрости и нелепости интерпретатора

greg zakharov пишет:
Yury пишет:

Если файл "example.txt" не существует, то он создаётся, если же этот файл существует, то он "опустошается" во избежание дозаписи.

Простите, но это что-то из области "CMD\BAT: камасутра".


greg zakharov, излагайти свои мысли так, чтобы они были понятны другим.

44

Re: CMD/BAT: Хитрости и нелепости интерпретатора

greg zakharov пишет:

alexii, тогда как назваться, если WinXP\7 триальные, живут под VirtualBox в Debian?

«Удачливым сукиным сыном» . Ибо пробная версия XP — достаточно большая редкость. У меня нет.

45 (изменено: Yury, 2014-12-18 05:30:24)

Re: CMD/BAT: Хитрости и нелепости интерпретатора

Rumata пишет:

Например, cd. трудна для восприятия, нужно задуматься, что тут происходит на самом деле.




cd.

-- это тоже самое, что

cd .

.
Команда изменяет текущий каталог на... текущий каталог.



cd..

-- это тоже самое, что и

cd ..

.
Команда изменяет текущий каталог на родительский каталог.





Rumata пишет:

В плане лаконичности call лучший кандидат.




rem+>1.txt
rem[>2.txt
rem]>3.txt
rem\>4.txt
rem/>5.txt
rem.>6.txt
rem,>7.txt
rem:>8.txt
rem;>9.txt

Всё те же символы, что и для "echo", за исключением "(" и "=".


Команда

rem=>example.txt

равносильна команде

rem >example.txt

,
то есть является обычным помещением комментария.


Удивительно, но знак равенства всё же работает, но только в такой конструкции:

for %%i in ("=") do rem%%~i>10.txt

.


Команда

rem(>example.txt

тоже создаст пустой файл, но с выводом ошибки:

"rem(" не является внутренней или внешней
командой, исполняемой программой или пакетным файлом.

.
То есть с таким же успехом пустой файл можно создать с помощью команды

Абракадабра 2>nul>example.txt

.


Кстати, применив команду "rem:" можно одновременно написать нужный комментарий и создать пустой файл. Например, в коде

rem: Мама мыла > раму.

" Мама мыла " -- это комментарий, а "> раму." -- это создание пустого файла "раму".

46

Re: CMD/BAT: Хитрости и нелепости интерпретатора

Yury, странно, что Вам пока не дали статус разработчика.

47 (изменено: Rumata, 2014-12-21 15:32:43)

Re: CMD/BAT: Хитрости и нелепости интерпретатора

http://ss64.com/nt/call.html

Недокументированное поведение команды call.
call команда (без двоеточия в начале) первым делом ВСЕГДА ищет исполнимый файл на диске, а потом запускает внутреннюю команду. То есть call set заведомо медленнее (из-за дисковых операций). То есть в циклических действиях следует избегать использования таких конструкций. Также это может привести к побочному эффекту если такой файл на диске существует! Проверено, это так и есть...

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

48 (изменено: wisgest, 2015-07-13 09:08:20)

Re: CMD/BAT: Хитрости и нелепости интерпретатора

Rumata пишет:

То есть call set заведомо медленнее (из-за дисковых операций). <…> Также это может привести к побочному эффекту если такой файл на диске существует! Проверено, это так и есть...

Подтверждаю и обещаю так не делать.
Впрочем, просматривается кое-какое достаточно очевидное решение,
не свободное от ипользования дисковых операций (в силу построчной обработки командных файлов),
но свободное от побочных эффектов:

добавить к командному файлу подпрограмму

:~
@%*
@exit /b

и вместо CALL КОМАНДА
писать CALL:~ КОМАНДА
, в том числе, если требуется неоднократное раскрытие переменных, вместо нескольких CALL подряд перед командой использовать столько же CALL:~

— Поведение, за исключением возможных побочных эффектов, кажется идентичным,
но не совсем:
а) появляется некоторая возможность использовать IF и FOR после CALL;
б) изменяется поведение GOTO (при последующей встрече с EXIT /B)
и EXIT /B (устанавливается %ERRORLEVEL%, но не происходит выход).

Хотя в последнем нет особой необходимости, но если вдруг понадобится использовать GOTO и EXIT /B с отложенным раскрытием их аргументов и без помощи вспомогательной переменной, то можно для этих команд написать отдельные подпрограммы, использующие переход на несуществующую метку

+ открыть спойлер
:goto
@(goto)2>nul & goto %*
:exit/b
@(goto)2>nul & exit /b %*

и вместо

call goto выражение_для_вычисления_метки
call exit /b выражение_для_вычисления_кода_возврата

писать

call :goto выражение_для_вычисления_метки
call :exit/b выражение_для_вычисления_кода_возврата

P.S. Можно заметить, что этим способом можно было сразу определить подпрограмму «~»:

:~
@(goto)2>nul & %*

но такой подход мне кажется мне кажется менее ясным и более ресурсозатратным,
а возможность при первом подходе использовать

call:~ exit /b число

для установки кода ошибки без возврата из подпрограммы — более полезной.

49 (изменено: Rumata, 2015-12-28 10:27:08)

Re: CMD/BAT: Хитрости и нелепости интерпретатора

По-видимому, нет возможности простым способом заэкранировать шаблон "?" и рассматривать его как простой символ.


for %f in ( "" "?" "/?" "-?" ) do @( echo:%f )
( 2 * b ) || ! ( 2 * b )

50

Re: CMD/BAT: Хитрости и нелепости интерпретатора

Именно в цикле? >

for /f "delims=" %# in ("^? /? -^?") do @(echo:%#)