Знание взаимодействия пакетных файлов Windows и функции Perl system () - PullRequest
3 голосов
/ 03 января 2012

Пример файла BATCH:

@echo off
echo starting
setlocal
cd c:\tmp
set A=B
perl -e "$ENV{X}='Y'; system('cmd')"
echo finished

Я запускаю этот скрипт (в Windows 7) с рабочим каталогом, установленным в c:\. Сценарий открывает, как и ожидалось, новую командную оболочку с набором рабочего каталогана c:\tmp и среда настроена так, как определено в моем скрипте.

В качестве следующего шага я сделал Control-C в этой оболочке, где меня попросили Terminate batch job (Y/N)?. Ответив на это Y, Я получил сообщение об ошибке:

'Y' is not recognized as an internal or external command, operable program or batch file.

Я получаю, однако, приглашение оболочки, текущий каталог отображается как c:\tmp.Допустим, я снова набираю Control-C.Теперь я вижу:

c:\tmp>^C
finished
c:\>

Моя подсказка показывает, что мой рабочий каталог вернулся к C:\ However, эта оболочка демонстрирует странное поведение. Если я неоднократно нажимаю ENTER в этой оболочке, я получаю следующий вывод:

c:\>

c:\tmp>

c:\>

c:\tmp>

Кроме того, я узнал, что у меня запущены две оболочки, поочередно получая свои данные: одна с рабочим каталогом, установленным на C:\, другая на C:\tmp.

Есть идеи, что здесь произошло?Может ли кто-нибудь с Windows 7 попробовать мой примерный пакетный скрипт с его / ее версией Perl?Кстати, я запускал его с использованием Perl 5.8.8, так как это версия, которая используется в этом проекте.

1 Ответ

0 голосов
/ 03 января 2012

Да, я вижу то же самое поведение.Ctrl + C каким-то образом проходит через передний план cmd.exe и применяется к родительскому процессу perl, который может быть уничтожен (в зависимости от ответа Y / N perl уничтожается вместе с пакетным заданием).Когда cmd находится в интерактивном режиме, он обычно игнорирует Ctrl + C, поэтому кажется, что он просачивается в родительский процесс.

Примечание: в результате у вас остаются две оболочки cmd, пытающиесячитать () один вход терминала.Как только кто-то читает строку, он обрабатывает ее, а другой переходит и получает возможность прочитать () следующую строку.И т. Д.

Обходной путь - заставить Perl игнорировать SIGINT:

perl -e "$SIG{INT} = 'IGNORE'; ... "

Вам нужно будет использовать exit для завершения cmd на переднем плане вместо Ctrl + C.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...