Приховані функції пакетних файлів Windows


232

Які є менш знаючі, але важливі та корисні функції пакетних файлів Windows?

Правила:

  • Одна особливість на відповідь
  • Дайте як короткий опис функції, так і приклад , а не лише посилання на документацію
  • Обмежуйте відповіді на власну функціональність , тобто не потребує додаткового програмного забезпечення, як-от Windows Resource Kit

Пояснення: ми посилаємося сюди на скрипти, які обробляються cmd.exe, що є типовим для варіантів WinNT.

(Див. Також: Пакетні файли Windows: .bat vs .cmd? )

Відповіді:


185

Продовження рядка:

call C:\WINDOWS\system32\ntbackup.exe ^
    backup ^
    /V:yes ^
    /R:no ^
    /RS:no ^
    /HC:off ^
    /M normal ^
    /L:s ^
    @daily.bks ^
    /F daily.bkf

2
Я шукав це минулого тижня! (не міг запам'ятати персонаж)
chilltemp

21
^ - це справді цитата. Використовуючи його, ви можете цитувати <і>, щоб вони не перенаправляли вихід. ^ В кінці рядка також дозволяє продовжити рядок.
Cheeso

Не могли б ви пояснити цей маленький сценарій?
guerda

2
@furtelwart: Це те ж саме , як якщо б ви написали все в один рядок: call C:\WINDOWS\system32\ntbackup.exe backup /V:yes /R:no /RS:no /HC:off /M normal /L:s @daily.bks /F daily.bkf. І щоб зрозуміти всі параметри цього рядка, просто запустіть C:\WINDOWS\system32\ntbackup.exe /?.
Курт Пфайфл

Поглиблена дискусія на цю тему, в довгих командах, розбитих на кілька рядків
jeb

150
PUSHD path

Переходить в каталог , вказаний шлях .

POPD

Повертає вас до каталогу, з якого ви "натиснули".


5
Це також працює як повний стек, тому ви можете натиснути багато каталогів на стек, а потім продовжувати з'являтися, щоб повернутися туди, де ви були.
Кіббі

Серйозно? Як я ніколи раніше не чув про цю особливість ?!
Джош Хінман

4
Запустіть 'cmd.exe', потім введіть 'help', а потім введіть 'help pushd' або 'pushd /?'.
paxdiablo

86
Якщо ви перейдете до контуру UNC, він автоматично відобразить диск для вас, і popd видалить його.
Ферруччо

2
+1, особливо для можливостей ООН, ви повинні додати це до своєї відповіді.
Адам Міц

109

Не впевнений, наскільки це було б корисно у пакетному файлі, але це дуже зручна команда для використання в командному рядку:

C:\some_directory> start .

Це відкриє Провідник Windows у папці "some_directory".

Я вважав це чудовим часом.


1
ну, я теж його використовую. У мене є файл "open.cmd" в одному з каталогів PATH, і єдине в цьому файлі - "@start." ;)
Павлій

5
"explorer" також робить те саме, що і "start" C: \ some_directory> explorer.
Промінь

1
Я схильний вводити це як [start "". ] (дужки для наочності), оскільки початок іноді хитро, коли перший парам є заголовком.
система ПАУЗА

1
Якщо ви трапляєтесь на Mac, open .робить те саме.
Грант Пол

1
startробить набагато більше, ніж просто відкрити поточну папку. Ви можете передати йому будь-який файл, і він відкриє його за допомогою налаштованого переглядача. Дайте йому URL-адресу, і ваш браузер за замовчуванням відкриється тощо ...
idbrii

87

Мені завжди складно читати коментарі, які позначені ключовим словом у кожному рядку:

REM blah blah blah

Легше читати:

:: blah blah blah

8
Я чув: :: є більш ефективним, ніж REM, тому що REM намагається зробити розширення змінної середовища на те, що відбувається після нього, але :: ні.
Скотт Ленгем

47
Насправді :: :: це лише лейбл із кумедною назвою; для цього :: :: не працюватиме, якщо використовувати його всередині блоку (в дужках), оскільки мітки також заборонені. REM працює, звичайно, там.
mihi

Зауважте, що remце ключове слово, яке документально підтверджене, а ::лише деталізація щодо реалізації. Хоча навряд чи це ::припинить роботу, загалом доцільно не покладатися на незадокументовану поведінку.
Джої

Ви навіть можете скористатися, goto :щоб перейти до мітки. :-)і goto -)також працюватиме.
Свен Марнах

79

Змінні підрядки:

> set str=0123456789
> echo %str:~0,5%
01234
> echo %str:~-5,5%
56789
> echo %str:~3,-3%
3456

3
Некрасивий, але дуже корисний!
guerda

1
@furtelwart звучить так, що може бути девізом партії
rzrgenesys187

це відмінно підходить для форматування дат (однак проблема, яку я знайшов, була те, що vista / 7 та xp виходять DATE по-різному)
Даніель,

Зауважте, що, на жаль, це не може поєднуватися з локальними змінними циклів FOR ( for %a in ...), оскільки їм не потрібен знак закриття відсотка, як і змінні середовища; спершу потрібно призначити їх змінній середовища (використовуючи затримку розширення!), а потім витягнути підрядку.
RolKau

Це неминуче потворне, якщо ви хочете зробити щось із датами (наприклад, імена резервних файлів). Переконавшись у загальній потворності командного рядка Windows, я бачу, чому Windows здебільшого вказує та натискає :) Хоча кажуть, що новий PowerShell краще.
Halil Özgür

72

Команда FOR ! Хоча я ненавиджу писати пакетні файли, я вдячний за це.

FOR /F "eol=; tokens=2,3* delims=, " %i in (myfile.txt) do @echo %i %j %k

проаналізував би кожен рядок у myfile.txt, ігноруючи рядки, які починаються з крапки з комою, передаючи 2-й та 3-й жетони від кожного рядка до тіла для тегів, розмежованих комами та / або пробілами. Зауважте, що для операторів body посилання% i для отримання 2-го маркера,% j для отримання 3-го маркера, і% k для отримання всіх залишилися лексем після 3-го.

Ви також можете використовувати це для повторення каталогів, вмісту каталогів тощо ...


4
Я виявив, що пакетні файли 'FOR циклів обмежені і страшно писати, але вони іноді корисні.
ya23

2
Вибачте моє здивування, але як на землі це не використовується? Я думаю, якщо ви не знаєте для циклів, ви не знаєте пакетних сценаріїв.
Кодування зі стилем

11
Невикористане чи ні, це катування. (Дехто заперечує необхідне зло.)
harpo

Мені довелося користуватися ним кілька разів, і людину, яка склала цей синтаксис, слід звільнити. З гармати. На сонце. Це ТО погано.
ВіталійБ

1
@CodingWithStyle: Кожен раз, коли мені потрібно записати цикл для циклу в пакетному файлі, скрипт стає баш-пусковим і замість нього переписати сценарій у bash (або python):
idbrii

60

Замість того, щоб замітати сценарій із рядками REM або ::, я виконую наступні дії у верхній частині кожного сценарію:

@echo OFF
goto :START

Description of the script.

Usage:
   myscript -parm1|parm2 > result.txt

:START

Зверніть увагу, як ви можете використовувати символи труби та перенаправлення, не уникаючи їх.


3
Було б ще крутіше, якби ви перевірили% 1 на "/?" і тоді ви можете повторити цей розділ як текст довідки.
demoncodemonkey

6
Гм, грамотне пакетне програмування ?!
Мухаммед Алькарурі

54

Шлях (з диском), де сценарій: ~ dp0

set BAT_HOME=%~dp0
echo %BAT_HOME%
cd %BAT_HOME%

Зазвичай я використовую для цього% CD%. Можливо, він доступний не у всіх версіях оболонки DOS?
Саул Долгін

11
% CD% - це поточна директорія, в той час як% ~ dp0 - каталог, де знаходиться запущений сценарій.
RealHowTo

Крім того, я не думаю, що% CD% існували раніше ... XP, можливо. Я знаю, що в старих версіях Windows цього немає.
Томас Оуенс

1
Ви повинні використовувати cd / d% BAT_HOME% замість цього, якщо кажан знаходиться на іншому диску. Якщо я добре пам’ятаю, все ж цей звичай не працює зі старими DOS.
ketorin

cd або pushd% BATH_HOME% не працюватиме, якщо запустити пакетну мережу.
Бенуа

49

Частка% ~ dp0 вже згадувалася, але насправді в ній є більше: персонаж (и) після ~ визначають інформацію, що вилучається.
Жодна літера не призводить до повернення імені файлу патчу
d - повертає букву диска
p - повертає шлях
s - повертає короткий шлях
x - повертає розширення файлу.
Отже, якщо ви виконаєте скрипт test.bat нижче від c: \ Temp \ long dir name \ папка,

@echo off
echo %0
echo %~d0
echo %~p0
echo %~dp0
echo %~x0
echo %~s0
echo %~sp0

Ви отримуєте наступний вихід

test
c:
\Temp\long dir name\
c:\Temp\long dir name\
.bat
c:\Temp\LONGDI~1\test.bat
\Temp\LONGDI~1\

І якщо параметр буде переданий у ваш сценарій, як у
тесті c: \ temp \ mysrc \ test.cpp,
ті ж маніпуляції можна виконати зі змінною% 1.

Але результат розширення% 0 залежить від місця розташування!
На "верхньому рівні" партії вона розширюється до поточного імені пакета.
У функції (виклик) вона розширюється до назви функції.

@echo off
echo %0
call :test
goto :eof

:test
echo %0
echo %~0
echo %~n0

Вихід є (batchfile запускається з myBatch.bat)

myBatch.bat
:test
:test
myBatch

43

За допомогою CALL, EXIT / B, SETLOCAL & ENDLOCAL можна реалізувати підпрограми з локальними змінними.

приклад:

@echo off

set x=xxxxx
call :sub 10
echo %x%
exit /b

:sub
setlocal
set /a x=%1 + 1
echo %x%
endlocal
exit /b

Це надрукується

11
xxxxx

незважаючи на те, що: sub змінює x.


6
Ви повинні скористатися goto: eof замість exit / b робить те саме, але є більш стандартним способом зробити це.
Філіберт Перус

2
Для цього є стандарт? O_o
Паулій

3
Моя помилка. Я думав, ти маєш на увазі чітко визначити етикетку: eof і зробити це для цього. Я не розумів, що в кінці кожного пакетного файлу є неявна: мітка eof.
Ferruccio

3
Однак, якщо ви хочете, щоб підпрограма встановила рівень помилок, вам потрібно буде використовувати exit / b. Наприклад: exit / b 3
Chris Noe

6
Я вважав, що найкраще використовувати "exit / B" замість "goto: eof" для повернення з підпрограми, "goto: eof" має проблему, що ви можете повернути код помилки, коли хочете проковтнути його. Наприклад, якщо ви використовуєте "якщо існує деякий ефірний ехо, це тут", це встановить рівень помилок, якщо деякого файлу не існує, але це не так, і це не код помилки, який ви хочете повернути (що саме " goto: eof "зробив би).
Скотт Ленгем

42

Підлий трюк, щоб зачекати N секунд (не є частиною cmd.exe, але не є додатковим програмним забезпеченням, оскільки він поставляється з Windows), дивіться рядок ping. Вам потрібно N + 1 пінг, оскільки перший пінг виходить без затримки.

    echo %time%
    call :waitfor 5
    echo %time%
    goto :eof
:waitfor
    setlocal
    set /a "t = %1 + 1"
    >nul ping 127.0.0.1 -n %t%
    endlocal
    goto :eof

2
Ще краще - помістити це у такий файл, як sleep.bat, щоб заощадити проблеми переписування його знову і знову.
erjiang

1
... і помістіть sleep.bat в деякий каталог змінної середовища PATH
Scoregraphic

Я проти того, щоб це ставити зовні, робить менш портативним ... для всіх систем Windows.
sorin

37

Втеча від "сантехніки":

echo ^| ^< ^> ^& ^\ ^^

3
Б'юсь об заклад, що персонаж втечі DOS не відомий. Хороший.
Джошуа

12
Ах, це пояснило б, чому це також оператор продовження лінії - він уникає нової лінії, як і \ у баші ...
арендуй

@leander: Так, але це може уникнути лише LF (а не CR), оскільки всі CR видаляються раніше
jeb

Так це чому використання Git на Windows , щоб дифф проти попередньої фіксації ( HEAD^) є проблематичним.
Даніель Треббієн

31

Можливість запускати команди та обробляти результат (на зразок зворотних посилань '$ ()' у баші).

for /f %i in ('dir /on /b *.jpg') do echo --^> %i

Якщо у назви файлів є пробіли, скористайтеся цим:

for /f "tokens=*" %i in ('dir /on /b *.jpg') do echo --^> %i

2
Не працює з назви файлів, які мають пробіли у своїх іменах ... Це працює: for / f "tokens = *"% i in ('dir / on / b * .jpg') echo - ^>% i
doekman

Хороший улов. Особисто я вважаю, що пробіли у назвах файлів - це злі огидні речі з глибини дев'ятого кола Пекла. Але, мабуть, ми повинні їх задовольнити.
paxdiablo

Це самий божевільний синтаксис, який я ще бачив. Чи працює, якщо ви створили цей backtick.bat і передаєте рядок?
idbrii

30

Створення порожнього файлу:

> copy nul filename.ext

6
@devio: відлуння. ставить порожній рядок. щоб файл не був порожнім!
Павлій

4
Я використовую type nul > filename.extдля цього.
Бенуа

Приємно, мені було цікаво, чи є сенсорний еквівалент тривалий час.
jdelator

Я завжди використовувавren > blah.txt
Synetech

28

Щоб приховати весь вихід з команди переспрямування на> nul 2> & 1.

Наприклад, деякі програми командного рядка відображають вихід, навіть якщо ви перенаправляєте на> nul. Але, якщо ви будете перенаправляти висновок, як рядок нижче, весь результат буде придушений.

PSKILL NOTEPAD >nul 2>&1

EDIT: Див. Ігнорування виводу команди для пояснення того, як це працює.


1
Чи знаєте ви, як це працює? У чому значення біта 2> & 1?
Скотт Ленгем

12
The> nul перенаправляє STDOUT на nul. 2> & 1 перенаправляє STDERR туди, куди вказує STDOUT.
афорія

Зокрема, я думаю, що 2> & 1 є "клоном файлових файлів", встановлюючи STDERR на клон STDOUT. Поставити його після> NUL важливо, тому що ви хочете клонувати STDOUT після того, як він був перенаправлений, а не раніше. (Будь ласка, виправте мене, якщо я тут помиляюся.)
орендар

1
Для тих, хто цікавиться, звідки береться PSKILL, перегляньте sysinternals.com . Якщо ви перебуваєте у виданні Pro, у вас повинна бути рідна команда TSKILL, яка більше-менш однакова.
Кодування зі стилем

1
Якщо у вас немає pskill або tskill, більшість систем Windows, якими я користувався, приходять taskkill.
idbrii

25
PAUSE

Зупиняє виконання та відображає таку підказку:

Натисніть будь-яку кнопку, щоб продовжити . . .

Корисно, якщо ви хочете запустити пакет, двічі клацнувши його в Провіднику Windows і хочете насправді побачити вихід, а не просто спалах вікна команд.


Навряд чи я б назвав це "недостатньо використаним", оскільки я позначаю це в кінці кожного написаного сценарію. Знову ж таки, це не працює настільки добре, коли ви хочете, щоб ваш IDE запустив сценарій і захопив висновок, оскільки IDE зазвичай не може натиснути клавішу enter для вас ...
Nicholas Flynt,

15
Однією акуратною особливістю "паузи" є те, що якщо немає терміналу навколо, щоб отримати "будь-який ключ" (наприклад, якщо ваш пакетний файл запускається від системної служби), він виявляє це і просто продовжує працювати ...
ліндвер

4
+1 Чарлі Сомервілл, це так відомо, що "go.bat" ігрового програміста використовував його ще на початку 90-х.
LiraNuna

6
Замість того, щоб забруднювати всі ваші пакетні файли (і робити їх дратівливим для використання для вундов CLI), ви можете використовувати Start / Run /, тоді введіть 'cmd / k' та ім'я пакетного файлу. АБО змінити HKCR \ batfile \ shell \ open \ командний рядок за замовчуванням на 'cmd / k "% 1"% *'. АБО зробіть ще один пакетний файл, який щойно виконує '@cmd / k $ *', покладіть його на робочий стіл і опустіть на нього інші файли. Є багато альтернатив ПАУЗІ. Будь ласка, врахуйте їх.
система ПАУЗА

1
@gnud: ви все ще можете передавати сценарій: echo.|batch-with-pause.batматиме такий самий ефект, як натискання клавіші "будь-яка клавіша" ...
Kurt Pfeifle

25

Еквівалент bash (та інших оболонок)

echo -n Hello # or
echo Hello\\c

який виводить " Hello" без кінцевого нового рядка. Зробити cmd-хак для цього:

<nul set /p any-variable-name=Hello

set /pце спосіб запросити користувача на введення. Він випускає заданий рядок і потім чекає (на тому ж рядку, тобто немає CRLF), щоб користувач ввів відповідь.

<nulпросто передає порожню відповідь на set /pкоманду, тому чистим результатом є випромінюваний рядок підказок. (Використовувана змінна залишається незмінною через порожній відгук.)

Проблеми: неможливо вивести провідний знак рівності, а на Vista провідні символи пробілу видаляються, але не на XP.


18

Шукайте та замінюйте, коли встановлюєте змінні середовища:

> @set fname=%date:/=%

... видаляє "/" з дати для використання в іменах файлів, розмічених часом.

і підрядки теж ...

> @set dayofweek=%fname:~0,3%

17

Арифметика цілого числа:

> SET /A result=10/3 + 1
4

Як довго SET має можливість розрахунку? Windows XP?
чакрит

1
Якщо ви запитуєте, наскільки великі можуть бути величини, я вважаю, що це 32-розрядні. Так +/- 2 мільярди.
Кріс Ное

1
Я думаю, що питання було, як довго SET може розраховувати? З Windows XP?
Майкл Майерс

3
Я все, що CMD.EXE SET зміг обчислити з NT 3.1 або близько того. Просто пройшло багато часу, щоб хтось помітив, що CMD.EXE не зовсім такий, як COMMAND.COM ...
RBerteig

16

Розділювачі команд:

cls & dir
copy a b && echo Success
copy a b || echo Failure

У другому рядку команда після && запускається лише в тому випадку, якщо перша команда успішна.

У 3-му рядку команда після || запускається, лише якщо перша команда не вдалася.



15

Ви можете зв'язати ланцюжок, якщо заяви отримують ефект, наприклад, булеві значення "та" короткого замикання.

if foo if bar baz

1
Це дійсно лише ярлик для вкладення ifs: if foo ( if bar ( baz ) )(Уявіть нові рядки після дужок.)
idbrii

14

Швидке перетворення текстового файлу Unicode (16 біт / char) у файл ASCII DOS (8 біт / char).

C:\> type unicodeencoded.txt > dosencoded.txt

як бонус, якщо можливо, символи правильно відображаються.


1
Це файл ANSI DOS - ASCII - 7 біт / char.
MarkJ

Lol, цей анти-шаблон, ця конверсія, швидше за все, не вдасться. Єдине 8-бітове кодування, що підтримує Unicode, є UTF-8, але завдяки M $ ви не можете встановити кодову сторінку UTF-8 у Windows.
sorin

14

якщо структура блоку:

if "%VS90COMNTOOLS%"=="" (
  echo: Visual Studio 2008 is not installed
  exit /b
)

3
Поки ви знаєте, що змінні будуть розширюватися все за один раз (без затримки розширення) - тобто ви не можете розумно використовувати% ERRORLEVEL% там.
Дункан Смарт

Ви також не можете використовувати там мітки (до яких належать ті коментарі :: стилі), оскільки це передчасно закінчиться оператором if.
Кодування зі стилем

2
@Duncan: Ні в якому разі не слід використовувати псевдо-змінну %ERRORLEVEL%; ось для чого if errorlevel <foo>. І що робить фактично працюють в таких блоках.
Joey

12

Затримка розширення змінних (з хорошими мірками, підкинуті підрядками):

    @echo off
    setlocal enableextensions enabledelayedexpansion
    set full=/u01/users/pax
:loop1
    if not "!full:~-1!" == "/" (
        set full2=!full:~-1!!full2!
        set full=!full:~,-1!
        goto :loop1
    )
    echo !full!
    endlocal

12

Не забезпечує багато функціональних можливостей, але ви можете використовувати команду заголовка для декількох застосувань, як-от надання статусу довгим сценарієм на панелі завдань або просто для покращення зворотного зв’язку з користувачем.

@title Searching for ...
:: processing search
@title preparing search results
:: data processing

2
Цікаво. Хоча після цього ви, очевидно, втрачаєте звичайну функцію, яка полягає в тому, щоб показати поточно запущену команду. Чи є можливість відновити це?
Кріс Ное

2
technet.microsoft.com/en-us/library/bb491017.aspx каже, що його можна скинути самостійно з "заголовком", але це, здається, не працює в Windows 7 ...
ℳ.

11

У вас немає зручного редактора і вам потрібно створити пакетний файл?

copy con test.bat

Просто введіть команди, натисніть клавішу Enter для нового рядка. Натисніть Ctrl-Z і Enter, щоб закрити файл.


4
Хе, це повертає мене назад.
Кодування зі стилем

11

приклад віднімання рядків dateі timeотримати файл під назвою "РРРР-MM-DD HH: MM: SS.txt"

echo test > "%date:~0,4%-%date:~5,2%-%date:~8,2% %time:~0,2%_%time:~3,2%_%time:~6,2%.txt"

Я використовую, colorщоб вказати, чи мій сценарій закінчився успішно, не вдався чи потрібен певний ввід, змінивши колір тексту та фону. Це дійсно допомагає, коли у вас є деяка машина, яка знаходиться в межах зору, але досить далеко

колір XY

де X і Y - шістнадцяткове значення від 0до F, де X - фон, Y - текст, коли X = Y колір не зміниться.

колір Z

змінює колір тексту на 'Z' та встановлює чорний фон, 'color 0' не працюватиме

для назв кольорів зателефонуйте

колір?


відредаговано; _ були інтерпретовані як курсив. Приємний шматочок коду.

@Duncan Smart: неправда, працює також англійською мовою Великобританії (хоча технічно це має бути "кольоровий", grrr)
demoncodemonkey

10

Повний контроль над висновком з пробілами та знаками пробігу

echo.    ^<resourceDir^>/%basedir%/resources^</resourceDir^>

1
Як це працює? Крапка визначає початок виведення тексту?
Кріс Ное

3
"ехо. х" виведе "<простір> х", "ехо х" видасть лише "х". Це дозволяє провідні місця. Крім того, символ "^" втечі заважає cmd думати про всі ті "<" і ">" символи - це перенаправлення вводу / виводу.
paxdiablo

1
echo (краще, тому що echo. створює пошук файлу за файлом під назвою "echo", якщо цей файл існує. echo. не вдається, якщо не тоді виконується внутрішнє ехо, але воно повільніше, ніж echo (
jeb

9

TheSoftwareJedi вже згадував команду for, але я знову згадаю про неї, оскільки вона дуже потужна.

Далі виводиться поточна дата у форматі YYYYMMDD, я використовую це під час створення каталогів для резервного копіювання.

for /f "tokens=2-4 delims=/- " %a in ('DATE/T') do echo %c%b%a

2
Безумовно, DATE / T повертається 29/10/2008 в Європі та 10/29/2008 в США ... тому може знадобитися деяка локалізація! ;-)

Це вірно! Але ви можете зловживати командою дати, щоб дізнатися, який формат дати використовується.
remonedo

4
Це надмірне використання FOR, imo. Я думаю, що я би просто використав% DATE: ~ 10,4 %% DATE: ~ 4,2 %% DATE: ~ 7,2% для цього, а не запустити команду date, а потім проаналізувати її для.
Кодування зі стилем
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.