spassen
spassen

Reputation: 1580

Batch FOR loop output showing whole command instead of just output when using PIPE

I'm attempting to send command output to a remote host using an SSH session established via Plink. My current command looks like the following (the infinite loop is intentional:

(for /l in %n (1,0,2) do ping 1.1.1.1 -n -w 1000 >nul & echo %RANDOM%) | plink.exe sessionName -l %user "cat > outputfile.txt"

I would expect outputfile.txt to contain a randomly generated number, but instead it contains this:

C:\(PATH)> ping 1.1.1.1 -n 1 -w 1000 1>nul & echo 9001

Why is the whole command being sent over, rather than just the random number?

As an aside, it's also appending to the remote file instead of rewriting. The remote host is Linux based, so I would expect it to rewrite the file since I'm using > and not >>.

Upvotes: 0

Views: 96

Answers (1)

aschipfl
aschipfl

Reputation: 34909

  1. A pipe creates a cmd.exe instance for either side, where for echoes its body code for every iteration. To avoid that, precede each command with @, or enclose the entire body within () and put a @ before the opening parenthesis, like this...:

    for /L %n in (1,0,2) do @ping 1.1.1.1 -n -w 1000 >nul & @echo %RANDOM%
    

    ...or this, respectively:

    for /L %n in (1,0,2) do @(ping 1.1.1.1 -n -w 1000 >nul & echo %RANDOM%)
    
  2. The in keyword is missing in the for /L command line, it must read:

    for /L %n in (1,0,2) do
    
  3. The for /L loop defines an infinite loop (I am not sure if you intend that), unless you change the step value to 1, like:

    for /L %n in (1,1,2) do
    
  4. To use the code in a (according to the tags), you need to double the % sign, like:

    for /L %%n in (1,1,2) do
    
  5. In the plink part there are unbalanced precent signs and quotation marks. For the remaining part herein, I assume it should read (since I do not know that tool):

    plink -l %user%
    
  6. The returned random number is going to be the same for every loop iteration, because variable %RANDOM% is expanded to (replaced by) a random number once the entire command line is parsed, unless you force delayed expansion:

    cmd /V /C "for /l %%n in (1,1,2) do @(ping 1.1.1.1 -n -w 1000 >nul & echo !RANDOM!)" | plink -l %user% > "outputfile.txt"
    

Upvotes: 3

Related Questions