3

Minimum working example:

test.bat:

@echo off
if 0==0 (
  timeout 3
  python test.py
)

test.py:

input('press ENTER to exit')

In cmd.exe:

call test.bat
> Waiting for 0 seconds, press a key to continue ...
> press ENTER to exit_

Then it's stuck at the input statement. If I keep pressing enter, it will eventually raise an exception:

Traceback (most recent call last):
  File "test.py", line 1, in <module>
    input('press ENTER to exit')
OSError: [WinError 8] Not enough storage is available to process this command

I'm on Windows 7 SP1, tried it with

  • Python 3.6 (64-bit)
  • Python 3.6 (32-bit)
  • Python 3.5 (32-bit)
  • Python 2.7 (32-bit) (in this case it's stuck forever without raising exception)

Can anyone reproduce this and/or have any idea where it went wrong?

Chenfeng
  • 197
  • 3
  • 11
  • Yes, I can reproduce that (Windows 7, Python 2.7), but I have no idea what is the cause. I believe `timeout` is messing around with the _stdin_ (`0`) handle. What happens when you try adding `<&3 3< nul` to the `timeout` command line? – aschipfl May 23 '18 at 18:36
  • 1
    Forget about the redirection thing `<&3 3< nul`, this has nothing to do with the code at hand -- sorry for confusion! Nevertheless, I found out that the `if` command may be removed, but the problem remains as long as the parentheses stay (or the two command lines are concatenated by `&`). As soon as `timeout` is replaced by `pause` (which reads from *std_in* too), everything works as expected. By the way, I can reproduce the problem also on Windows 7 with Python 2.6, but I can't on Windows 10 (with Python 2.7)... – aschipfl May 23 '18 at 21:09
  • are you asking why this bug exists, or how you can overcome it? – Gerhard May 24 '18 at 06:55
  • @Gerhard Barnard Both, I guess? – Chenfeng May 24 '18 at 21:02
  • please do me a favour, open regedit, goto `HKEY_LOCAL_MACHINE\system\CurrentControlSet\Control\Session Manager\SubSystems` the is a `Windows` value. Open it and scroll to the right until you find something like `SharedSection=1024,2048,256` and let me know what this value is. – Gerhard May 25 '18 at 05:50
  • I found `SharedSection=1024,20480,768` – Chenfeng May 25 '18 at 15:39

2 Answers2

2

I can reproduce the issue on Windows 7 with Python 3.6.5 64 bit.

A couple of alternatives to avoid the issue with timeout:

@echo off
if 0==0 (
  echo Pause for 3 seconds
  ping -n 3 localhost >nul
  python test.py
)
exit /b

This uses ping which causes no issue.

@echo off
if 0==0 (
  timeout 3
  call :run_python test.py
)
exit /b

:run_python
python %*
exit /b

This uses a label named :run_python which allows the interpreter to run Python outside the context of the parentheses. Any arguments passed following the called label will be passed to python.

michael_heath
  • 5,262
  • 2
  • 12
  • 22
  • To wait for 3 seconds you actually need `ping -n 4` to have 4 attempts and three pause intervals... – aschipfl May 25 '18 at 16:56
1

Yes, I can reproduce the behavour you observed on Windows 7 with Python 2.6 and Python 2.7, but not on Windows 10 with Python 2.7. The file sizes of timeout.exe differ between Windows 7 and Windows 10, so there have been changes to that command.

I believe that timeout messes around with the file pointer in the STD_IN stream (handle 0), particularly because it moves the pointer for displaying the seconds countdown (see this thread: Clear a line/move the cursor, using the Timeout command or similar).

The problem does not only occur together with the if command, it comes up as soon as timeout and the Python script call are in the same parenthesised block of code:

(
    timeout 3
    python test.py
)

The same issue happens when they are in the same line:

timeout 3 & python test.py

When the two command lines are in separate lines without parentheses, it works fine:

timeout 3
python test.py

As soon as the timeout command is replaced by pause, which also reads from STD_IN, everything works as expected:

(
    pause
    python test.py
)

Or also:

pause & python test.py

michael_heath already provided a nice work-around in his answer using ping. However, this cannot be aborted by a key-press like timeout (so it is actually equivalent to timeout 3 /NOBREAK).

aschipfl
  • 33,626
  • 12
  • 54
  • 99