Как подавить подтверждение "Прервать пакетное задание (Y/N)"?
В cmd, когда мы нажимаем Ctrl+C, мы завершаем работу целевого приложения, но если целевое приложение вызывается из пакетного файла, мы получаем это подтверждение "Завершить пакетное задание (Y/N)". Я никогда не могу вспомнить случай, когда я решил не прерывать пакетное задание. Как мы можем пропустить это подтверждение?
17 ответов
AFAIK вы не можете, так как это поведение разработано и контролируется интерпретатором команд. Нет способа "отобразить" или даже "перехватить" это, если вы не декомпилируете и не перекомпилируете интерпретатор напрямую.
На этом сайте я нашел эффективное решение:
script2.cmd < nul
Чтобы не приходилось печатать это каждый раз, когда я сделал второй скрипт script.cmd
в той же папке со строкой выше. Я тестировал эту технику только на XP, но другие подтвердили ее на Win 7.
Натан добавляет: другой вариант - поместить следующий код в начало файла script.cmd, который делает то же самое в одном файле:
rem Bypass "Terminate Batch Job" prompt.
if "%~1"=="-FIXED_CTRL_C" (
REM Remove the -FIXED_CTRL_C parameter
SHIFT
) ELSE (
REM Run the batch with <NUL and -FIXED_CTRL_C
CALL <NUL %0 -FIXED_CTRL_C %*
GOTO :EOF
)
Установите Clink и измените настройку terminate_autoanswer. Файл настроек должен быть здесь: C:\Users\<username>\AppData\Local\clink\settings
,
# name: Auto-answer terminate prompt
# type: enum
# Automatically answers cmd.exe's 'Terminate batch job (Y/N)?' prompts. 0 =
# disabled, 1 = answer 'Y', 2 = answer 'N'.
terminate_autoanswer = 1
Это тогда "просто работает" с любым окном cmd.exe. Вам не нужно изменять то, что работает или что-то иное, так как кликните копилки на cmd.exe.
Черт возьми, ИМО!
Если вам не нужно ничего делать в командном файле после нормального завершения приложения, используйте start
Команда гарантирует, что пакетный файл уже завершен к тому времени, когда вы нажимаете Ctrl-C. И, следовательно, сообщение не появится.
Например:
@ эхо выключено set my_command=ping.exe установить my_params=-t www.google.com Команда echo, которая будет выполнена командой start:% my_command%% my_params% :: Если НЕ использовать /B или /WAIT, то это создаст новое окно, а:: выполнение этого самого пакетного файла будет продолжено в текущем окне: start% my_command%% my_params% эхо. echo Эта строка будет выполнена ДО того, как 'start' будет даже закончен. Итак, это Пакетный файл echo будет завершен ДО того, как вы нажмете Ctrl-C в другом окне. эхо. :: Просто для тестирования используйте "пауза", чтобы показать "Нажмите любую клавишу, чтобы продолжить", чтобы увидеть:: вывод команд 'echo'. Обязательно нажмите Ctrl-C в окне:: который запускает команду ping (не в этом самом окне). Или просто удалить:: следующая строка в замешательстве: Пауза
(Проверено на Windows XP.)
Я боролся с этим желанием на некоторое время избежать приглашения "Завершить пакетную работу".
Мое последнее прозрение - это ловкость рук (или окно консоли), заменив один экземпляр cmd.exe
с другим. Это достигается путем выполнения команды / программы через start cmd /k
followed immediately by exit
в .BAT
файл.
The original console window disappears and the replacement one can be stopped cleanly via Ctrl-C.
Consider the following example of a traceroute
которые могут быть прерваны с помощью Ctrl+C или разрешены для завершения, возвращая пользователя к C:\>
незамедлительный:
@echo off
set timeout=100
if not "%2"=="" set timeout=%2
start cmd /k tracert -w %timeout% %1
exit
Замена окружения на новый командный интерпретатор может быть не для всех, но, на мой взгляд, выглядит и работает хорошо для меня.
Решение Gringo хорошо, но не работает со скриптами, которые передают список аргументов (т.е. python myscript.py %*
), поскольку SHIFT
не обновляет %*
, Есть обходные пути, но у них есть определенные ограничения.
Вот модификация, с которой я закончил:
IF [%JUSTTERMINATE%] == [OKAY] (
SET JUSTTERMINATE=
python myscript.py %*
) ELSE (
SET JUSTTERMINATE=OKAY
CALL %0 %* <NUL
)
99. (9)% безупречно.
TCC/LE, который является бесплатной заменой CMD (воспринимается как CMD++), имеет возможность подавить запрос на завершение пакетного задания. Вы можете найти эту опцию в диалоге настройки запуска TCC:
Отмена пакетного файла на Ctrl-C: Отмена обработки пакетного файла без обычной подсказки при нажатии Control-C.
Скриншот:
Если вы никогда раньше не слышали о TCC/LE, вот несколько замечаний с сайта:
TCC/LE является заменой командной строки CMD (командная строка Windows по умолчанию). TCC/LE - это расширенный набор CMD с 111 внутренними командами (в CMD менее 40), 240 внутренними переменными и функциями и сотнями улучшений существующих команд CMD.
TCC/LE работает с вашими существующими приложениями командной строки и пакетными файлами, но предлагает значительные улучшения в возможностях командной строки и пакетных файлов и добавляет тысячи новых функций в окна командной строки.
Я использовал TCC/LE в течение многих лет и 4NT до этого. Я очень люблю это и могу рекомендовать это. Единственная причина, по которой я до сих пор не использую его, заключается в том, что я почти исключительно использую PowerShell сейчас.
Смотрите этот вопрос переполнения стека.
Тем не менее, исправление cmd.exe не то, что я бы сделал для этого.
Решение с использованием AutoHotkey
Загрузите и установите AutoHotkey
Создайте скрипт (например
terminate.ahk
)Вставьте следующий скрипт
#SingleInstance Force
#IfWinActive ahk_exe cmd.exe
^d::terminate()
#IfWinActive ahk_exe powershell.exe
^d::terminate()
terminate()
{
SendInput {Ctrl down}c{Ctrl up}
Sleep 100
SendInput y{Enter}
}
- Выполнить сценарий
Теперь, когда вы Ctrl+Dнажимаетеpowershell.exe
илиcmd.exe
Ctrl+C y Enterотправляется последовательность, которая завершает программу .
Если вы хотите настроить горячую клавишу, см. Список клавиш.
Если вы хотите применить эту горячую клавишу к другой программе, просто добавьте ее в скрипт (например,Visual Studio Code
->code.exe
):
#IfWinActive ahk_exe code.exe
^d::terminate()
Название программы можно найти по адресуTask Manager > Details
Основная причина подавления "Завершения пакетного задания (Y/N)" - запуск программы в цикле (например, повторный запуск в случае сбоя).
Это https://stackoverflow.com/a/8185270/1170023 помогло привести к этому решению:
@ECHO OFF
rem assumes you have installed pslist from sysinternals to windows PATH
:RUN
echo Starting GoldenEye Dedicated Server
start "" srcds.exe -console -game gesource +maxplayers 16 +map ge_complex
:LOOP
pslist srcds >nul 2>&1
if ERRORLEVEL 1 (
goto RUN
) else (
rem echo Dedicated server is still running
timeout /t 5 >nul
goto LOOP
)
В моем случае именно файл ping.bat, который находился прямо в моем пользовательском каталоге (C:\Users\ в Vista или C:\Documents and Settings\ в XP), неопределенно удерживал пакетное задание.
Этот пакетный файл выполнялся всякий раз, когда я запускал ping из командной строки, где текущим каталогом является мой пользовательский каталог. Пинг из окна "Выполнить" или из каталога другого пользователя работал нормально.
Удалил файл из моего пользовательского каталога, и проблема была решена!
Я столкнулся с этим с EXE-файлом, который, казалось, выдавал ^C родительскому пакету при выходе, вызывая запрос "Завершить пакетное задание" даже при чистом выходе.
Решением, которое я выбрал, было запускать пакет с "Пуск", аналогично другим ответам, но из приглашения PowerShell (или, если хотите, с помощью метода интерпретатора PowerShell из CMD).
Сейчас 2018 год, и в Windows 10 Microsoft начала вытеснять CMD с PowerShell в качестве предпочтительной командной строки, поэтому по умолчанию она легко доступна в графическом интерфейсе.
Start
это псевдоним для Start-Process.
При запуске просто запускается и возвращается. Поэтому, когда вы останавливаете запущенный процесс, подсказка "Завершить пакетное задание" отсутствует.
По умолчанию он не ждет, поэтому никаких дополнительных аргументов помимо команды и ее аргументов не требуется.
С помощью start mything.exe -mythings -arguments
в моей партии работал отлично.
В сценариях PowerShell должен быть указан путь к запуску, поэтому я запускаю свой командный файл как .\host.bat
,
Пуск работает, но теперь окно, открытое командным файлом, изменилось по сравнению с опциями, которые у меня были, и "свойства" отключены (не отвечает).
Просто перенаправьте пакетный стандартный ввод в ноль, добавив
В конце вашего сценария просто добавьте следующую команду: echo
Это не "повредит" поведению вашего скрипта, и, кажется, мешает CDM спросить, хотите ли вы прекратить пакет.