Can you redirect the output of a command to a variable with pipes?
I haven't tried much as I haven't been able to think of anything to try, but I have tried one method (with two variations)...
For example:
echo Hello|set text= Didn't work, neither did:
echo Hello | set text= I know you can do it fairly easily with the FOR command, but I think it would look "nicer" with a pipe.
And if you're wondering, I don't have a specific reason I'm asking this other than I'm curious and I can't find the answer.
36 Answers
Your way can't work for two reasons.
You need to use set /p text= for setting the variable with user input.
The other problem is the pipe.
A pipe starts two asynchronous cmd.exe instances and after finishing the job both instances are closed.
That's the cause why it seems that the variables are not set, but a small example shows that they are set but the result is lost later.
set myVar=origin echo Hello | (set /p myVar= & set myVar) set myVar Outputs
Hello origin Alternatives: You can use the FOR loop to get values into variables or also temp files.
for /f "delims=" %%A in ('echo hello') do set "var=%%A" echo %var% or
>output.tmp echo Hello >>output.tmp echo world <output.tmp ( set /p line1= set /p line2= ) echo %line1% echo %line2% Alternative with a macro:
You can use a batch macro, this is a bit like the bash equivalent
@echo off REM *** Get version string %$set% versionString="ver" echo The version is %versionString[0]% REM *** Get all drive letters `%$set% driveLetters="wmic logicaldisk get name /value | findstr "Name"" call :ShowVariable driveLetters The definition of the macro can be found at
SO:Assign output of a program to a variable using a MS batch file
The lack of a Linux-like backtick/backquote facility is a major annoyance of the pre-PowerShell world. Using backquotes via for-loops is not at all cosy. So we need kinda of setvar myvar cmd-line command.
In my %path% I have a dir with a number of bins and batches to cope with those Win shortcomings.
One batch I wrote is:
:: setvar varname cmd :: Set VARNAME to the output of CMD :: Triple escape pipes, eg: :: setvar x dir c:\ ^^^| sort :: ----------------------------- @echo off SETLOCAL :: Get command from argument for /F "tokens=1,*" %%a in ("%*") do set cmd=%%b :: Get output and set var for /F "usebackq delims=" %%a in (`%cmd%`) do ( ENDLOCAL set %1=%%a ) :: Show results SETLOCAL EnableDelayedExpansion echo %1=!%1! So in your case, you would type:
> setvar text echo Hello text=Hello The script informs you of the results, which means you can:
> echo text var is now %text% text var is now Hello You can use whatever command:
> setvar text FIND "Jones" names.txt What if the command you want to pipe to some variable contains itself a pipe?
Triple escape it, ^^^|:
> setvar text dir c:\ ^^^| find "Win" 3THIS DOESN'T USE PIPEs, but requires a single tempfile
I used this to put simplified timestamps into a lowtech daily maintenance batfile
We have already Short-formatted our System-Time to HHmm, (which is 2245 for 10:45PM)
I direct output of Maint-Routines to logfiles with a $DATE%@%TIME% timestamp;
. . . but %TIME% is a long ugly string (ex. 224513.56, for down to the hundredths of a sec)
SOLUTION OVERVIEW:
1. Use redirection (">") to send the command "TIME /T" everytime to OVERWRITE a temp-file in the %TEMP% DIRECTORY
2. Then use that tempfile as the input to set a new variable (I called it NOW)
3. Replace
echo $DATE%@%TIME% blah-blah-blah >> %logfile%
with
echo $DATE%@%NOW% blah-blah-blah >> %logfile%
====DIFFERENCE IN OUTPUT:
BEFORE:
SUCCESSFUL TIMESYNCH 29Dec14@222552.30
AFTER:
SUCCESSFUL TIMESYNCH 29Dec14@2252
ACTUAL CODE:
TIME /T > %TEMP%\DailyTemp.txt SET /p NOW=<%TEMP%\DailyTemp.txt echo $DATE%@%NOW% blah-blah-blah >> %logfile%
AFTERMATH:
All that remains afterwards is the appended logfile, and constantly overwritten tempfile. And if the Tempfile is ever deleted, it will be re-created as necessary.
I find myself a tad amazed at the lack of what I consider the best answer to this question anywhere on the internet. I struggled for many years to find the answer. Many answers online come close, but none really answer it. The real answer is
(cmd & echo.) >2 & (set /p =)<2
The "secret sauce" being the "closely guarded coveted secret" that "echo." sends a CR/LF (ENTER/new line/0x0D0A). Otherwise, what I am doing here is redirecting the output of the first command to the standard error stream. I then redirect the standard error stream into the standard input stream for the "set /p =" command.
Example:
(echo foo & echo.) >2 & (set /p bar=)<2
5In a batch file I usually create a file in the temp directory and append output from a program, then I call it with a variable-name to set that variable. Like this:
:: Create a set_var.cmd file containing: set %1= set /p="set %%1="<nul>"%temp%\set_var.cmd" :: Append output from a command ipconfig | find "IPv4" >> "%temp%\set_var.cmd" call "%temp%\set_var.cmd" IPAddress echo %IPAddress% 1You can set the output to a temporary file and the read the data from the file after that you can delete the temporary file.
echo %date%>temp.txt set /p myVarDate= < temp.txt echo Date is %myVarDate% del temp.txt In this variable myVarDate contains the output of command.