set /p problems with pipes

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
penpen
Expert
Posts: 2009
Joined: 23 Jun 2013 06:15
Location: Germany

Re: set /p problems with pipes

#16 Post by penpen » 29 Jan 2015 18:10

This looks like a double buffer bug (Edit: wrong, see next post); i just slightly modified your "test.bat":

Code: Select all

@echo off

(
   echo start
   ping -n 2 localhost > nul
   for %%c in (H e l l "o " w o r l d) do @set /p "=[%%~c]" <nul
   echo(
   echo Data from pipe
) | (
   find /V ""
   REM you could also use this
   REM findstr "^"
)
goto :eof

Result:

Code: Select all

Z:\>test
start
[H]
Data from pipe
[e]
Data from pipe
[l]
Data from pipe
[l]
Data from pipe
[o ]
Data from pipe
[w]
Data from pipe
[o]
Data from pipe
[r]
Data from pipe
[l]
Data from pipe
[d]
Data from pipe
The first buffer received "[H]\0[e]\0[l]\0[l]\0[o ]\0[w]\0[o]\0[r]\0[l]\0[d]\0" and the second one contains "Data from pipe\r\n\0"; \0 == NUL byte == 0x00.
But i'm not sure if the bug is generated on the "data source" or the "sink" side of the anonymous pipe (worst case 2 bugs on both ends):
I cannot image that the data "Data from pipe" is not consumed by the "sink" side(find /V ""),
but it is also odd that "[...]" parts are not send as one part, and the second buffer data sends multiple times.

Maybe two parallel (not synchronized) sending threads (C1, C2) with own buffers at the data source side.

penpen

Edit: PS: I still think there is no timeout (set /P): http://www.dostips.com/forum/viewtopic.php?p=28896#p28896
Edit2: I have added the "(Edit...)" part.
Last edited by penpen on 30 Jan 2015 01:23, edited 1 time in total.

jeb
Expert
Posts: 1055
Joined: 30 Aug 2007 08:05
Location: Germany, Bochum

Re: set /p problems with pipes

#17 Post by jeb » 29 Jan 2015 18:24

dbenham wrote:Is someone warping the space time continuum :?:

You get what you test 8)

penpen wrote:This looks like a double buffer bug; i just slightly modified your "test.bat":

No, it's really simple.

Code: Select all

(
for %%c in (H e l l o) do echo #%%c
echo END
)


This is absolutly NOT the same as this

Code: Select all

(
for %%c in (H e l l o) do echo #%%c
echo END
)|more


The pipe will start a new cmd.exe instance (as you know), but you forget the folding.
The new block will be folded into

Code: Select all

( FOR %c in (H e l l o) do echo #%c & echo END )


So, now the FOR loops over the complete code behind the FOR loop :!:


Now with a more robust code

Code: Select all

@echo off
(
   echo start
   ping -n 2 localhost > nul
   echo a
   ping -n 2 localhost > nul
   echo b
   ping -n 2 localhost > nul
   echo c

   for /L %%n in (1 1 112) do echo %%n
) | (
   @for /L %%n in (1 1 20) do @set var=. & @set /p var= & @set var&@echo(

)


As you can see the set /p waits for the first three inputs.
But then it's random what numbers are read :!:

Output wrote:var=start
var=a
var=b
var=c
var=.
var=12
var=22
var=33
var=44
var=55
var=66
var=82
var=.
var=104
var=.
var=.
var=.
var=.
var=.
var=.


So my guess for the pipe rule is:
1) set /p waits for input
2) When set /p reads from the buffer, it only reads to the first CR, but linefeeds can be read. The rest of the buffer is discarded
3) ??? I don't understand why it sometimes can still read nothing (I know: english syntax/spelling is wrong here)
EDIT: Not longer a problem, see the next post


Proof of the linefeed reading

Code: Select all

@echo off
setlocal
set LF=^


set "clean=set var=."
@echo off
(
   <nul set /p .=one^^%%LF%%%%LF%%two
   echo three
   echo four
   ping -n 3 localhost > nul
   echo a
) | (
   ping -n 2 localhost > nul
   @for /L %%n in (1 1 20) do @set var=. & @set /p var= & @set var&@echo(
)


Jan Erik

jeb
Expert
Posts: 1055
Joined: 30 Aug 2007 08:05
Location: Germany, Bochum

Re: set /p problems with pipes

#18 Post by jeb » 29 Jan 2015 18:51

jeb wrote:You get what you test 8)

Arrrg :evil:
I found my bug :!:

It's essential to add @ to every and all commands, else the "ECHO Feature" will confuse the results.

Code: Select all

@echo off
(
   @echo start
   @for /L %%n in (1 1 40) do @(
      <nul set /p .=%%n-
   )
) | (
   @(
      for /L %%n in (1 1 60) do @(
         set var=
         set /p var=
         set var
      )
   )
)


This gives the expected result of
Output wrote:var=start
var=5-
var=6- 7-
var=8- 9-
var=10-
var=11-
var=12- 13-
var=14-
var=15-
var=16- 17-
var=18-
var=19-
var=20-
var=21- 22-
var=23-
var=24-
var=25- 26-
var=27-
var=28-
var=29-
var=30-
var=31- 32-
var=33-
var=34-
var=35-
var=36- 37-
var=38-
var=39-
var=40-
var=
var=
var=
var=
...


The "start" is there and all numbers from 5 to 40.
The 1 to 4 are dropped as they are behind the "start<CR><LF>"

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: set /p problems with pipes

#19 Post by dbenham » 29 Jan 2015 22:27

I am relieved to know the universe is indeed safe after all. Thanks, jeb, for the reminder about the folding. :D

All I needed to fix my original test case was an extra set of parentheses around the entire FOR compound statement.

jeb wrote:Arrrg :evil:
I found my bug :!:

It's essential to add @ to every and all commands, else the "ECHO Feature" will confuse the results.

Actually you only need @ at the start of each FOR DO clause. Your original code was missing the @ after the DO on the left side.

I did some more experiments, and it appears my joke about the dual nature of SET /P with piped data is actually true :!:

I believe that when reading piped data, SET /P waits indefinitely for input to appear in the buffer. But once it begins to see data, it continues to read until either the buffer is full, or a timeout occurs. That is the only logical explanation I can think of for the following behavior: (Note - we already know it does not stop reading upon <CR> or <LF>)

Code: Select all

@echo off
(
   echo START 1
   echo START 1A
   ping -n 2 localhost > nul
   (for %%c in (H e l l "o " w o r l d) do @set /p "=[%%~c]" <nul)
   echo END 1
   echo END 1A
   ping -n 2 localhost > nul
   echo START 2
   echo START 2A
   (for %%c in (H e l l "o " w o r l d) do @set /p "=[%%~c]" <nul)
   echo END 2
   echo END 2A
   ping -n 2 localhost > nul
   echo FINISH
   echo FINISH B
)|for /l %%N in (1 1 25) do @(
  set "var=----"
  set /p "var="
  set var
)

--OUTPUT-- (Note - I inserted <pause...> to indicate where there is a delay in the output due to PING)

Code: Select all

C:\test>test
var=START 1
<pause...>
var=[H]
var=[e]
var=[l]
var=[l]
var=[o ]
var=[w]
var=[o][r]
var=[l]
var=[d]END 1
<pause...>
var=START 2
var=START 2A
var=[e]
var=[l]
var=[l][o ]
var=[w]
var=[o]
var=[r]
var=[l][d]
var=END 2
<pause...>
var=FINISH
var=FINISH B
var=----
var=----
var=----

C:\test>test
var=START 1
<pause...>
var=[H]
var=[e]
var=[l]
var=[l]
var=[o ]
var=[w]
var=[o][r]
var=[l]
var=[d]END 1
<pause...>
var=START 2
var=START 2A
var=[e]
var=[l][l]
var=[o ]
var=[w]
var=[o][r]
var=[l]
var=[d]
var=END 2
<pause...>
var=FINISH
var=FINISH B
var=----
var=----
var=----

C:\test>test
var=START 1
<pause...>
var=[H]
var=[e]
var=[l]
var=[l]
var=[o ]
var=[w]
var=[o]
var=[r][l]
var=[d]
var=END 1
<pause...>
var=START 2
var=START 2A
var=[e]
var=[l]
var=[l][o ]
var=[w]
var=[o]
var=[r]
var=[l][d]
var=END 2
<pause...>
var=FINISH
var=FINISH B
var=----
var=----


Dave Benham

penpen
Expert
Posts: 2009
Joined: 23 Jun 2013 06:15
Location: Germany

Re: set /p problems with pipes

#20 Post by penpen » 30 Jan 2015 01:20

jeb wrote:
penpen wrote:This looks like a double buffer bug; i just slightly modified your "test.bat":

No, it's really simple.
(...)
The pipe will start a new cmd.exe instance (as you know), but you forget the folding.
Oh, you are right! :oops:
In addition i just should have known that such a "bug" should quickly be noticed by everyone, so this was a wrong assumption... .
(Last night it was too late, i assume: Sorry.)

dbenham wrote:I believe that when reading piped data, SET /P waits indefinitely for input to appear in the buffer. But once it begins to see data, it continues to read until either the buffer is full, or a timeout occurs. That is the only logical explanation I can think of for the following behavior: (Note - we already know it does not stop reading upon <CR> or <LF>)
When reading your examples, i still couldn't see any reason for a timeout handling of the set/P command. The following (set/P implementation) pseudo code should produce the same output:

Code: Select all

while (0 == Console.in.Read (envVariable.buffer, 0, 1023)) {};

penpen

jeb
Expert
Posts: 1055
Joined: 30 Aug 2007 08:05
Location: Germany, Bochum

Re: set /p problems with pipes

#21 Post by jeb » 30 Jan 2015 01:24

dbenham wrote:I believe that when reading piped data, SET /P waits indefinitely for input to appear in the buffer. But once it begins to see data, it continues to read until either the buffer is full, or a timeout occurs. That is the only logical explanation I can think of for the following behavior: (Note - we already know it does not stop reading upon <CR> or <LF>)

Hmm, I don't think so. :)

Like penpen said:
Output wrote:When reading your examples, i still couldn't see any reason for a timeout handling of the set/P command.


There is no timeout, it simply waits until something is in the buffer, but when the buffer is not empty it read the complete buffer.
Only when the pipe is closed by the producer, SET /p will be able to read empty lines.

When there would be a timeout, you should be able to get empty lines before, but in your sample you never saw this.

Slow down the producer

Code: Select all

@echo off
(
   echo One
   ping -n 2 localhost > nul
   (for %%c in (H e l l "o " w o r l d) do @call call call call set /p "=[%%~c]" <nul)
   echo END
)|for /l %%N in (1 1 25) do @(
  set "var=----"
  set /p "var="
  set var
)


Output wrote:var=One
var=[H]
var=[e]
var=[l]
var=[l]
var=[o ]
var=[w]
var=[o]
var=[r]
var=[l]
var=[d]
var=END
var=----
var=----
var=----
...


But when you slow down the consumer

Code: Select all

@echo off
(
   <nul set /p "=One"
   (for %%c in (H e l l "o " w o r l d) do @set /p "=[%%~c]" <nul)
   ping -n 2 localhost > nul
   echo END   
)|for /l %%N in (1 1 25) do @(
   call call set "var=----"
  set /p "var="
  set var
)


Output wrote:var=One[H][e][l][l][o ][w][o][r][l][d]
var=END
var=----
var=----
....

dbenham
Expert
Posts: 2461
Joined: 12 Feb 2011 21:02
Location: United States (east coast)

Re: set /p problems with pipes

#22 Post by dbenham » 30 Jan 2015 07:50

Let us all assume the following discussion deals only with SET /P reading piped data.

penpen wrote:
dbenham wrote:I believe that when reading piped data, SET /P waits indefinitely for input to appear in the buffer. But once it begins to see data, it continues to read until either the buffer is full, or a timeout occurs. That is the only logical explanation I can think of for the following behavior: (Note - we already know it does not stop reading upon <CR> or <LF>)

When reading your examples, i still couldn't see any reason for a timeout handling of the set/P command. The following (set/P implementation) pseudo code should produce the same

Code: Select all

while (0 == Console.in.Read (envVariable.buffer, 0, 1023)) {};


I don't see how that gives the results we see with SET /P generated input that has no <CR> or <LF>

So how does my SET /P generated input end up as multiple lines lines? The buffer is not full, so why does the receiver generally put each character as a new line? If the SET /P were to continue to read until the buffer were full, then I would expect [h][e][l][l][o ][w][o][r][l][d] all on one line.

jeb wrote:There is no timeout, it simply waits until something is in the buffer, but when the buffer is not empty it read the complete buffer.

Ahh - that last bit is the key point - exactly what buffer are you referring to?

I thought we were in agreement that SET /P has its own 1023 byte buffer that it populates until some trigger tells it to stop, and only then does SET /P process the buffer and load the variable, discarding everything after the first <CR>.

We know that SET /P never reads more than 1023 bytes (the SET /P buffer size). So buffer full is one stop trigger. But what stops SET /P when the sender is "slowly" sending one character at a time? There must be some kind of timing issue - if there is additional data waiting in the pipe buffer, than SET /P continues reading, but at some point SET /P sees that there is no data waiting, so it triggers the end and SET /P finishes.

I was calling the timing issue a timeout, but perhaps it is simply a race condition. SET /P could be filling its buffer as fast as it can, and if there is no data wating in the pipe buffer, then it could terminate immediately.

I was assuming there must be some kind of timeout, because sometimes I get multiple SET /P sender outputs as one line of input in the receiver. If there were not a timeout condition, then I was thinking that the SET /P loop reading data from the pipe would always be significantly faster than multiple SET /P statements from the sender, so they should all be on separate lines. But sometimes the sender manages to squeeze two SET /P outputs into a single receiver input. I thought the only way that could happen is if there was some kind of timeout condition on the receiver end.


Dave Benham

Aacini
Expert
Posts: 1913
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: set /p problems with pipes

#23 Post by Aacini » 30 Jan 2015 13:04

I comed across this problem when I wanted to modify this SO answer trying to eliminate the auxiliary file used as signal that the first process had completed the input, so such input be taken from the pipe itself. The keypoint in the new method was that when a SET /P command read from the pipe and there is not data available, it immediately continue with no modification of the variable. It not worked, so I posted my previous report.

I further modified the second method trying to insert the new ideas posted here. It still not works. The last code is below, the modifications are in uppercase letters.

Code: Select all

@echo off
setlocal EnableDelayedExpansion

rem Execute a SET /P command with time out
rem Antonio Perez Ayala

rem If this file is re-executed as pipe's right side, go to it
if "%~1" equ "TimeoutMonitor" goto %1

(
   ECHO SEND SOME CHARS, SO BUFFER BE NOT EMPTY

   set /P "line=You have 10 seconds to complete this input: " > CON
   call set /P "=%%line%%" < NUL
   echo/
) 2> NUL | "%~F0" TimeoutMonitor 10 > InputLine.txt
set /P "line=" < InputLine.txt
del InputLine.txt
echo Line read: "!line!"
goto :EOF


:TimeoutMonitor

rem Get the PID of pipe's left side
tasklist /FI "IMAGENAME eq cmd.exe" /FO TABLE /NH > tasklist.txt
for /F "tokens=2" %%a in (tasklist.txt) do (
   set "leftSidePipePID=!lastButOnePID!"
   set "lastButOnePID=%%a"
)
del tasklist.txt

REM CONSUME THE FIRST CHARS IN PIPE, THIS SET /P DON'T WAITS
SET /P "LINE="

rem Wait for the input line, or until the number of seconds passed
set "line="
for /L %%i in (1,1,%2) do (
   ping -n 2 localhost > NUL
   set /P "line="
   if defined line echo !line!& exit /B
)

rem Time out: kill the SET /P command and create a standard input line
taskkill /PID %leftSidePipePID% /F > NUL
echo/> CON
echo Time Out

exit /B

This program allows to show several strange points:

  • If you omit the SET /P "LINE=" that consume the first chars in pipe, we expect that the program terminate immediately with "SEND SOME CHARS..." as line read. Instead, it still waits for the user input, but after Enter key is pressed the program show "SEND SOME CHARS..." as line read, NOT the line entered!!!
  • If you change the ECHO SEND SOME CHARS... by a REM (yes, by a REM!), then several strange things happen:
    • Neither the SET /P prompt nor the user input appears in the screen.
    • THE PROGRAM ENDS AFTER THE SPECIFIED 10 SECONDS DELAY!!! :shock: This happens no matter if the user completed the input before that time.
    • The command window is closed! You may avoid this point if you start an additional cmd.exe before run the program.
    • If you started another cmd.exe as said before, then, after the program ends, THE LINE ENTERED BY THE USER IS EXECUTED IN THE COMMAND LINE!!!
    • In all previous cases, the InputLine.txt file, that is not deleted, contains "Time Out".

This is the output screen of my test:

Code: Select all

C:\> cmd
Microsoft Windows [Versión 6.2.9200]
(c) 2012 Microsoft Corporation. Todos los derechos reservados.

C:\> rem After executed next line, I typed "echo This is crazy!" and pressed enter in a couple seconds:

C:\> TimedInput.bat

C:\> echo This is crazy!
This is crazy!

C:\> type InputLine.txt
Time Out

C:\>

:?: :?: :?: :?: :?: :?: :?: :?: :?:

Antonio
Last edited by Aacini on 30 Jan 2015 13:17, edited 2 times in total.

penpen
Expert
Posts: 2009
Joined: 23 Jun 2013 06:15
Location: Germany

Re: set /p problems with pipes

#24 Post by penpen » 30 Jan 2015 13:06

dbenham wrote:There must be some kind of timing issue - if there is additional data waiting in the pipe buffer, than SET /P continues reading, but at some point SET /P sees that there is no data waiting, so it triggers the end and SET /P finishes.
I'm not sure if i may misunderstand (this part of) your post.
Do you assume that if the pipe is performing a write, and a read operation then the read operation is blocked (by the pipe) until the write operation is finished (interuptable by timeout)?

The set/P (function) doesn't know how much data will be passed to the pipe (buffer) by a foreign process.
It accesses just the read method of the pipe (via the actual set up (default) input stream).

At this level i have to admit, that it may be possible that someone creates a pipe that has such timeout events, as it is not forbidden (as far as i know; i would have to read into).
But i never have seen such a construct.

All pipe implementation (that i have seen) somehow synchronize the read/write operations.
Such a pipe may then block the write operation if there is more data to write than fits in the pipe buffer, but the write operation never blocks the read operation.
Typically there is another (blocking) read function, that guarantees to read at least one atomic data value.

In most cases this is guaranteed by a cyclic buffer; example:
======
atomic data value field (simple buffer): buffer
offset: start, end // data begins at start index and ends at index end
If the end of the buffer is reached (read/write) the next data atomic data value to process is at index 0, (1, 2, ...).

Contract of all subclasses:
The read operation is only allowed to change the start offset value,
while the write operation is only allowed to change the end offset value.
======

So the pipe read operation returns ((start <= end) ? (end-start) : (buffer.length+end-start)) atomic data values.
It doesn't matter if a write operation is in progress/has partially written its content to the pipe buffer/...: The read operation is non blocking.

Up to now i've not seen a situation in which such a "timing construct" may be useful, and it offers the possibility of (unexpected) deadlocks, so i doubt someone has implemented a pipe that way.

dbenham wrote:I was assuming there must be some kind of timeout, because sometimes I get multiple SET /P sender outputs as one line of input in the receiver. If there were not a timeout condition, then I was thinking that the SET /P loop reading data from the pipe would always be significantly faster than multiple SET /P statements from the sender, so they should all be on separate lines. But sometimes the sender manages to squeeze two SET /P outputs into a single receiver input. I thought the only way that could happen is if there was some kind of timeout condition on the receiver end.
The actual order of write and read operations is influenced by mutlitasking/multithreading/multiprocessing.
If you receive multiple sender outputs in one line, then the "sender just has good luck" on mutlitasking/multithreading/multiprocessing.
For example: The taskmanager in common does not guarantee, that all processes have the same amount of processor time per "step".


dbenham wrote:I don't see how that gives the results we see with SET /P generated input that has no <CR> or <LF>

So how does my SET /P generated input end up as multiple lines lines? The buffer is not full, so why does the receiver generally put each character as a new line? If the SET /P were to continue to read until the buffer were full, then I would expect [h][e][l][l][o ][w][o][r][l][d] all on one line.
Producing one of the the above results. Let A be the data source, B be the sink process ("A|B"), and P be the pipe:

Code: Select all

Process A                      output        Process B

P.write("START 1\r\n", 0, 9);                 9 == P.read(var.buffer, 0, 1023); -> var = "START 1"
                               var=START 1
                               <pause...>
P.write("[H]", 0, 3);                         3 == P.read(var.buffer, 0, 1023); -> var = "[H]"
                               var=[H]
P.write("[e]", 0, 3);                         3 == P.read(var.buffer, 0, 1023); -> var = "[e]"
                               var=[e]
P.write("[l]", 0, 3);                         3 == P.read(var.buffer, 0, 1023); -> var = "[l]"
                               var=[l]
P.write("[l]", 0, 3);                         3 == P.read(var.buffer, 0, 1023); -> var = "[l]"
                               var=[l]
P.write("[o ]", 0, 4);                        4 == P.read(var.buffer, 0, 1023); -> var = "[o ]"
                               var=[o ]
P.write("[w]", 0, 3);                         3 == P.read(var.buffer, 0, 1023); -> var = "[w]"
                               var=[w]
P.write("[o]", 0, 3);
P.write("[r]", 0, 3);                         6 == P.read(var.buffer, 0, 1023); -> var = "[o][r]"
                               var=[o][r]
P.write("[l]", 0, 3);                         3 == P.read(var.buffer, 0, 1023); -> var = "[l]"
                               var=[l]
P.write("[d]", 0, 3);
P.write("END 1\r\n", 0, 7);                  10 == P.read(var.buffer, 0, 1023); -> var = "[d]END 1\r\n"
                               var=[d]END 1

(...)                          (...)         (...)

penpen

penpen
Expert
Posts: 2009
Joined: 23 Jun 2013 06:15
Location: Germany

Re: set /p problems with pipes

#25 Post by penpen » 30 Jan 2015 14:26

Aacini wrote:
  • If you omit the SET /P "LINE=" that consume the first chars in pipe, we expect that the program terminate immediately with "SEND SOME CHARS..." as line read. Instead, it still waits for the user input, but after Enter key is pressed the program show "SEND SOME CHARS..." as line read, NOT the line entered!!!
No, the following line could be reached earlier (and it seems this variation is more/most probable).So you have to type some input first.

Code: Select all

set /P "line=You have 10 seconds to complete this input: " > CON
There are various reasons why the data receiving process may be blocked.
For example if the set/P command synchronizes with the pipe object by locking a monitor, then the receiver process has to wait until the set/p has released the monitor lock.

If i see it right, then the text "SEND SOME CHARS..." is the first data in the pipe buffer, so this is ok.


Aacini wrote:
  • If you change the ECHO SEND SOME CHARS... by a REM (yes, by a REM!), then several strange things happen:
    • Neither the SET /P prompt nor the user input appears in the screen.
if i understand you right, then i did a similar error last night:
dbenham wrote:The pipe will start a new cmd.exe instance (as you know), but you forget the folding.
The new block will be folded into

Code: Select all

( FOR %c in (H e l l o) do echo #%c & echo END )
So the sender part of the piped processes will be folded to (i'm unsure about the ')' character):

Code: Select all

( REM ... )
So this codeblock is executed fast and produce no.
The result on my Win XP differs from what you describe then (because of that i'm unure if i have done the "REM thing" right), so i finish here.


penpen

Aacini
Expert
Posts: 1913
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: set /p problems with pipes

#26 Post by Aacini » 30 Jan 2015 16:27

penpen wrote:The result on my Win XP differs from what you describe then (because of that i'm unure if i have done the "REM thing" right), so i finish here.


penpen


Excuse me, I am afraid I don't follow you... Could you help me to clear this matter? Please, do the following:

Copy mi code above, run it, enter your name, wait more than 10 seconds and press Enter, and post a copy of the screen. Then, change this line:

Code: Select all

   ECHO SEND SOME CHARS, SO BUFFER BE NOT EMPTY

... by this one:

Code: Select all

   REM SEND SOME CHARS, SO BUFFER BE NOT EMPTY

... and repeat previous steps. TIA!

Just for completeness, this is what I see with the original code:

Code: Select all

C:\> test
You have 10 seconds to complete this input: Antonio
Line read: "Antonio"


Antonio

penpen
Expert
Posts: 2009
Joined: 23 Jun 2013 06:15
Location: Germany

Re: set /p problems with pipes

#27 Post by penpen » 30 Jan 2015 17:58

Obviously i had done something wrong with the code last time... (i was too lazy, to copy paste it twice...).
The result that time was an Dialog with:
- the Titel "Windows - Disk drive not ready",
- the "white X on red ball" icon, and
- the Message "Exception Processing message x00000a3 Parameters 75b0bf7c 4 75b0bf7c 75b0bf7c".
Sorry for irritating you, the result now is much better:

Code: Select all

Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

Z:\>echo start: %time% & test & call echo end:   %^time%
start:  0:28:47,54
Der Befehl "tasklist" ist entweder falsch geschrieben oder
konnte nicht gefunden werden.
Der Befehl "taskkill" ist entweder falsch geschrieben oder
konnte nicht gefunden werden.

Line read: "Time Out"
end:    0:28:58,10

Z:\>penpen
Der Befehl "penpen" ist entweder falsch geschrieben oder
konnte nicht gefunden werden.

Z:\>
The explaination of the behaviour is simple:
You rem out the first process (folding).
=> the first process finishes before the first set/P of the receiving process
=> so the pipe buffer is empty and closed
=> set/P... result in reading failed (you may check the errorlevel (==1)
your taskkill killed the cmd instance
(
taskkill failed on my win xp
=> echo "Time Out" (-> redirected to InputLine.txt), exit /B
=> line := InputLine.txt, deleted InputLine.txt, echo line (== "Time Out")
)

My typed name was buffered in the console input buffer, and is read by the command line after the program ends, so it tried to execute penpen (=> not found).


penpen

Edit: Actually i have no idea why your name ("Antonio") seems to be redirected to the file "InputLine.txt", but i'm probably too tired... . To all goodnight!

Post Reply