I Feel Dumb Asking This, But What Are Pipes For?

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
nitt
Posts: 218
Joined: 22 Apr 2011 02:43

I Feel Dumb Asking This, But What Are Pipes For?

#1 Post by nitt » 10 May 2011 15:15

If I use the "|"'s, it just does the last thing. Like, "echo hi | echo dog" will return "dog". And sometimes, it will say the pipe is incorrect.

I've never used these "pipes" before, so I'm just wondering what they are for and if they important.

aGerman
Expert
Posts: 4689
Joined: 22 Jan 2010 18:01
Location: Germany

Re: I Feel Dumb Asking This, But What Are Pipes For?

#2 Post by aGerman » 10 May 2011 16:26

Nah, don't feel stupid. It's only a question of the right commands ...
A pipe will transfer the standard-output stream of one command to the next, provided that the second command can process it. That means it doesn't make any sense to pipe the output of ECHO to another ECHO.
This is an example to show where a pipe could be useful: -
Granted that you have a variable and you want to compare this variable with a string, then you normally would try something like that:

Code: Select all

@echo off &setlocal
set "var=EXAMPLE"
if "%var%"=="EXAMPLE" (
  echo the value of %%var%% is EXAMPLE
) else (
  echo the value of %%var%% isn't EXAMPLE
)
pause

Perfect solution, isn't it. But only if the variable value is exactly the same :wink:
What happens if the variable contains a sentence where EXAMPLE is only a sub string? An IF statement won't work in this case. FIND or FINDSTR are able to find sub strings, but normally they are made to search in files. At this point you could use the pipe.
Have a look at that code

Code: Select all

@echo off &setlocal
set "var2=this is an EXAMPLE to show how a pipe works"
echo %var2%|findstr "EXAMPLE" >nul &&(
  echo the value of %%var2%% contains the sub string EXAMPLE
)||(
  echo the value of %%var2%% does't contain the sub string EXAMPLE
)
pause

FINDSTR returns errorlevel 0 if EXAMPLE was found, otherwise it returns errorlevel 1. && and || can handle it.

Regards
aGerman

nitt
Posts: 218
Joined: 22 Apr 2011 02:43

Re: I Feel Dumb Asking This, But What Are Pipes For?

#3 Post by nitt » 24 May 2011 19:53

aGerman wrote:Nah, don't feel stupid. It's only a question of the right commands ...
A pipe will transfer the standard-output stream of one command to the next, provided that the second command can process it. That means it doesn't make any sense to pipe the output of ECHO to another ECHO.
This is an example to show where a pipe could be useful: -
Granted that you have a variable and you want to compare this variable with a string, then you normally would try something like that:

Code: Select all

@echo off &setlocal
set "var=EXAMPLE"
if "%var%"=="EXAMPLE" (
  echo the value of %%var%% is EXAMPLE
) else (
  echo the value of %%var%% isn't EXAMPLE
)
pause

Perfect solution, isn't it. But only if the variable value is exactly the same :wink:
What happens if the variable contains a sentence where EXAMPLE is only a sub string? An IF statement won't work in this case. FIND or FINDSTR are able to find sub strings, but normally they are made to search in files. At this point you could use the pipe.
Have a look at that code

Code: Select all

@echo off &setlocal
set "var2=this is an EXAMPLE to show how a pipe works"
echo %var2%|findstr "EXAMPLE" >nul &&(
  echo the value of %%var2%% contains the sub string EXAMPLE
)||(
  echo the value of %%var2%% does't contain the sub string EXAMPLE
)
pause

FINDSTR returns errorlevel 0 if EXAMPLE was found, otherwise it returns errorlevel 1. && and || can handle it.

Regards
aGerman


Ya... I still don't get it. Can you use a wee bit simpler examples?

Ed Dyreen
Expert
Posts: 1569
Joined: 16 May 2011 08:21
Location: Flanders(Belgium)
Contact:

Re: I Feel Dumb Asking This, But What Are Pipes For?

#4 Post by Ed Dyreen » 24 May 2011 20:12

Code: Select all

@echo off

( if 0 equ 1 ( echo. yes &echo.the answer was yes ) else echo. no right? ) &echo.ok then
echo.hello |>nul findstr "nopes" &&echo.nopes found ||echo.nopes not found
echo.nopes |>nul findstr "nopes" &&echo.nopes found ||echo.nopes not found

pause
exit

Cleptography
Posts: 287
Joined: 16 Mar 2011 19:17
Location: scriptingpros.com
Contact:

Re: I Feel Dumb Asking This, But What Are Pipes For?

#5 Post by Cleptography » 24 May 2011 20:44

type file.txt | findstr "some string"

instead of

findstr "some string" "file.txt"

orange_batch
Expert
Posts: 442
Joined: 01 Aug 2010 17:13
Location: Canadian Pacific
Contact:

Re: I Feel Dumb Asking This, But What Are Pipes For?

#6 Post by orange_batch » 25 May 2011 01:28

nitt wrote:Ya... I still don't get it. Can you use a wee bit simpler examples?


Code: Select all

set /p "name=What's your full name?: "


Imagine the user enters the name Gary John Smith. The following will find John anywhere within %name%.

Code: Select all

echo:%name%|(find "John"&&echo:"John" was found in your name.||echo:"John" was not found in your name.)


This is a short way to do the same thing here:

Code: Select all

echo:%name%|find "John"
rem If find found "John", %errorlevel% is set to 0.
rem If find did not find "John", %errorlevel% is set to any number other than 0.
if %errorlevel%==0 (
echo:Found "John".
) else (
echo:Did not find "John".
)

rem Even shorter...
if %errorlevel%==0 (echo:Found "John".) else echo:Did not find "John".


Or even...

Code: Select all

echo:%name%|find "John"&&(
echo:Found "John".
)||(
echo:Did not find "John".
)

DOS can do some shit in all kinds of ways. :P

So, the short way uses logical AND (&&) and logical OR (||). This is a generic way of error handling. (I say generic because, it works for %errorlevel%==0 or %errorlevel% NEQ 0, but not matching any specific %errorlevel% that a command returns that isn't 0, like 1, 2, 3, whatever...)

Explanation:

Say you have... command A&&command B||command C
Command B only executes if command A is successful. Command C only executes if either command A or command B fail.

Say you have... command A&&(command B||command C)
Command B only executes if command A is successful. Command C only executes if command B fails.

Save you have... command A||(command B&&command C)
Command B only executes if command A fails. Command C only executes if command B is successful.

You can continue to group the logic like this forever, really.
Last edited by orange_batch on 26 May 2011 06:38, edited 1 time in total.

VernGraner
Posts: 2
Joined: 25 May 2011 14:55

Re: I Feel Dumb Asking This, But What Are Pipes For?

#7 Post by VernGraner » 25 May 2011 15:22

nitt wrote:If I use the "|"'s, it just does the last thing. Like, "echo hi | echo dog" will return "dog". And sometimes, it will say the pipe is incorrect. I've never used these "pipes" before, so I'm just wondering what they are for and if they important.

Lets try a very simple example here - say you just want to know how much space is free on your C drive. You could do this:

Code: Select all

DIR

Of course, this would return the entire directory listing, finishing with the free space as shown here:

Code: Select all

<stuff omitted above>
04/29/2008  10:18 AM    <DIR>          Batches
10/26/2009  03:37 PM    <DIR>          Start Menu
04/24/2007  07:05 PM    <DIR>          WINDOWS
05/12/2007  11:19 PM               260 x.log
04/29/2008  10:12 AM             1,058 Xrm.txt
              22 File(s)        477,064 bytes
              22 Dir(s)  68,948,930,560 bytes free
C:\>

So, it would be nice to filter this output so you don't see anything but the line that has the free space in it. A good command for this is "FIND".

However, FIND is designed to operate on a file. So, to use FIND, first you would have to create a file using redirection of the DIR command to a new file called "temp.txt" like this:

Code: Select all

c:\>DIR >temp.txt

Then, you would have to read that file with FIND like this:

Code: Select all

C:\>find "bytes free" temp.txt

---------- TEMP.TXT
              20 Dir(s)  68,948,271,104 bytes free

So, wouldn't it be nice if you could take the output of DIR and send it DIRECTLY to the FIND command? Sorta like connecting a "pipe" between the "out" of DIR and "in"of FIND? That's exactly what pipe does. :) So, here's how to take DIR and PIPE its output through FIND to show only the free space on a drive:

Code: Select all

C:\>dir | find "bytes free"
              20 Dir(s)  68,948,267,008 bytes free

Hope this helps! ;)

Vern

nitt
Posts: 218
Joined: 22 Apr 2011 02:43

Re: I Feel Dumb Asking This, But What Are Pipes For?

#8 Post by nitt » 25 May 2011 15:41

VernGraner wrote:
nitt wrote:If I use the "|"'s, it just does the last thing. Like, "echo hi | echo dog" will return "dog". And sometimes, it will say the pipe is incorrect. I've never used these "pipes" before, so I'm just wondering what they are for and if they important.

Lets try a very simple example here - say you just want to know how much space is free on your C drive. You could do this:

Code: Select all

DIR

Of course, this would return the entire directory listing, finishing with the free space as shown here:

Code: Select all

<stuff omitted above>
04/29/2008  10:18 AM    <DIR>          Batches
10/26/2009  03:37 PM    <DIR>          Start Menu
04/24/2007  07:05 PM    <DIR>          WINDOWS
05/12/2007  11:19 PM               260 x.log
04/29/2008  10:12 AM             1,058 Xrm.txt
              22 File(s)        477,064 bytes
              22 Dir(s)  68,948,930,560 bytes free
C:\>

So, it would be nice to filter this output so you don't see anything but the line that has the free space in it. A good command for this is "FIND".

However, FIND is designed to operate on a file. So, to use FIND, first you would have to create a file using redirection of the DIR command to a new file called "temp.txt" like this:

Code: Select all

c:\>DIR >temp.txt

Then, you would have to read that file with FIND like this:

Code: Select all

C:\>find "bytes free" temp.txt

---------- TEMP.TXT
              20 Dir(s)  68,948,271,104 bytes free

So, wouldn't it be nice if you could take the output of DIR and send it DIRECTLY to the FIND command? Sorta like connecting a "pipe" between the "out" of DIR and "in"of FIND? That's exactly what pipe does. :) So, here's how to take DIR and PIPE its output through FIND to show only the free space on a drive:

Code: Select all

C:\>dir | find "bytes free"
              20 Dir(s)  68,948,267,008 bytes free

Hope this helps! ;)

Vern


Ooh... Now I think I get it...

So how ">" sends the output to a file, the "|", or pipe sends the output to another command?

Can you give more examples, instead of the FIND and DIR command?

VernGraner
Posts: 2
Joined: 25 May 2011 14:55

Re: I Feel Dumb Asking This, But What Are Pipes For?

#9 Post by VernGraner » 25 May 2011 16:15

nitt wrote:Can you give more examples, instead of the FIND and DIR command?

I don't have the time at the moment to type up another example, but there are some really good descriptions on this site:

http://ss64.com/nt/syntax-redirection.html

Hope this helps. :)

Vern

Cleptography
Posts: 287
Joined: 16 Mar 2011 19:17
Location: scriptingpros.com
Contact:

Re: I Feel Dumb Asking This, But What Are Pipes For?

#10 Post by Cleptography » 25 May 2011 16:38

ss64 does have some good explanations for this not disregarding DosTips of course both sites are wonderful. Piping commands can be useful for shortening up things a bit.

On an XP machine to list drives and types one might use one method

Code: Select all

@echo off
 setlocal

::
REM Get and list drive types using fsutil
::
   set "list="
   
   for /f "tokens=*" %%a in ('^
   fsutil fsinfo drives^|^
   find /V ""'

) do (

   set "dv=%%a"
 call set "list=%%list%% %%dv:~-3%%"
)
   for %%a in (%list%) do (
   fsutil fsinfo drivetype %%a
)


...which does not translate to win7
You might use some piped commands...

Code: Select all

@echo off

echo.list vol | DiskPart | find /i "partition"
echo.list vol | DiskPart | find /i "DVD-ROM"
echo.list vol | DiskPart | find /i "Removable"

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

Re: I Feel Dumb Asking This, But What Are Pipes For?

#11 Post by dbenham » 25 May 2011 16:49

Bear in mind that most commands do not make use of the input provided by the pipe. Besides FIND and FINDSTR, there is MORE. I'm sure there are others, but I don't remember off the top of my head.

Also, the pipe is most useful if the input does not yet exist in a file. If the input file does exist already, then it is usually faster to use it directly instead of using the pipe.

findstr "some string" "file.txt" is faster than type file.txt | findstr "some string"

Dave Benham

orange_batch
Expert
Posts: 442
Joined: 01 Aug 2010 17:13
Location: Canadian Pacific
Contact:

Re: I Feel Dumb Asking This, But What Are Pipes For?

#12 Post by orange_batch » 26 May 2011 06:47

One use for redirection is automating a response to another command. I can't think of a particular command that you can't override with a switch at the moment, but for example...

del foldername
Asks to delete all files within foldername.

echo:y|del foldername
Automatically enters "y" when it asks.



del foldername /q
This is the switch to skip asking for this particular command, but some commands don't have such a switch.

nitt
Posts: 218
Joined: 22 Apr 2011 02:43

Re: I Feel Dumb Asking This, But What Are Pipes For?

#13 Post by nitt » 26 May 2011 14:01

orange_batch wrote:One use for redirection is automating a response to another command. I can't think of a particular command that you can't override with a switch at the moment, but for example...

del foldername
Asks to delete all files within foldername.

echo:y|del foldername
Automatically enters "y" when it asks.



del foldername /q
This is the switch to skip asking for this particular command, but some commands don't have such a switch.


Oh, thanks. I think I'm starting to get it and all.

Post Reply