Say I have the command:
python --version > PythonVersion.txt
A file called PythonVersion.txt is created. In my case the contents are "Python 3.9.13".
Can the output of a command be saved as a variable? I'd like to be able to do something like the following:
#echo off
set "PythonVersion=python --version"
echo Your Python installation is: %PythonVersion%
The expected output might be Your Python installation is: Python 3.9.13, but of course the above script isn't valid and produces Your Python installation is: python --version.
#echo off
for /F "delims=" %%a in ('python --version') do #set lastline=%%a
echo.%lastline%
If the output is multiple lines, you might have to filter the command output with ^| find ... to just get the line you are interested in (unless you want the last line) because for will loop until there are no more non-empty lines...
Related
I am trying to convert my bash script into a Windows batch file. It's a really simple one liner that's supposed to feed the contents of a file as arguments to script.exe, and send the results to output.txt.
This is the working bash script:
./script.exe $(cat input.txt) > output.txt
I know this might be bad style, but it works. The problem is, I have no idea how to do something like $() in a windows batch file. When I use it it sends the string "$(cat input.txt)" as the argument instead of running the command.
This bash construct is called command substitution. Here is a great answer from #MichaelBurr.
You can get a similar functionality using cmd.exe scripts with the
for /f command:
for /f "usebackq tokens=*" %%a in (`echo Test`) do my_command %%a
Yeah, it's kinda non-obvious (to say the least), but it's what's
there.
See for /? for the gory details.
Sidenote: I thought that to use "echo" inside the backticks in a
"for /f" command would need to be done using "cmd.exe /c echo
Test" since echo is an internal command to cmd.exe, but it works
in the more natural way. Windows batch scripts always surprise me
somehow (but not usually in a good way).
See also, on Superuser: Is there something like Command Substitution in WIndows CLI?
As stated here Is it possible to set an environment variable to the output of a command in cmd.exe I always used that
mycommand.exe>%TEMP%\out.txt
set /P FOO=<%TEMP%\out.txt
But that's ugly because it creates a file.
The for method is better but complicated
I wanted something simple a la unix, like:
mycommand.exe|set /P FOO=
No error, but FOO is not set after I run that.
Why is this not working?
Best way I can think of doing this would be to create your own little batch file that silently uses the FOR construct. For instance, you could create a batch named BatchSet.bat, stored somewhere on your path. The batch would contain the following code:
#Echo off
for /f "delims=" %%i in ('%2') do set %1=%%i
Set %1
If you run this with the following command:
BatchSet MyVar whoami
You'll get something like:
MyVar=servername\John
Obviously, the command you run should limit its output to a single line to be stored properly in the environment variable.
For instance, if you run it like this:
BatchSet MyVar Vol
Then you'll only get the first line of the Vol command's output
MyVar= Volume on drive C is labeled MyDisk
But all in all, it's a fairly elegant way of doing what you were looking for.
Note that the last line in the batch is simply there to provide visual output. It can be removed altogether.
I tried to customize windows command prompt with the following batch file.
#echo off
cls
:cmd
set /p "cmd=%cd%>"
%cmd%
goto cmd
So, when I open the batch file, it just takes my command into cmd variable and executes it and again prompts for a new command.
But the following command echo %cd% outputs only %cd%
Then I enabled delayedexpansion and used echo !cd! and got the desired output.
I think, because of the delayed expansion, cmd variable now holds echo c:\Users\Sourav\Desktop (am I correct?)
But I got confused when I tried to open the command prompt (not the batch file) and tried the following commands.
I thought, I will get c:\Users\Sourav\Desktop but I got !cd!. This contradicts my understanding of how echo !cd! is working in first case.
Why am I getting different output in the second case?
Can anyone suggest any improvement to the batch file, so that I can get desired output just using echo %cd% in first case?
you need another level of parsing. You can use call to do so:
#echo off
cls
:cmd
set /p "cmd=%cd%>>"
call %cmd%
goto cmd
I'm a bit of a noob to batch programming. I've got this very small and simple code to do some stuff with Tuppers self-referential formula:
java -jar Tuppers.jar --read-image <img file you want to read>
I have the image file in a folder called Read. So I use this command line:
java -jar Tuppers.jar --read-image Read\*
since I will only have one file at a time in that folder.
I wanna set a variable num to the result of the function and then echo it out, but if I use
set /p num = java -jar Tuppers.jar --read-image Read\*
then its just gonna set the variable to the command line.
For /f "delims=" %A in ('java -jar Tuppers.jar --read-image Read\*') do echo %A
See for /? and use %%A in a batch file and %A when typing.
The standard output of any Windows command line program can be picked up in various ways.
Redirection to a file via > and >>
Piping to another command via |
And in your case picked up as a line of output. Try this from the command line:
for /f "tokens=*" %i in ('java -jar Tuppers.jar --read-image Read\*') do set myvar=%i
After that myvar, which you can check the contents of via "echo %myvar%", will contain the last line output from the java command.
Note that for this to work your java Tuppers.jar needs to print the number you want to standard output.
In a batch file, I am trying to fetch the output of a command and save it to a variable.
The goal of my command is to count the number of folders in a certain folder.
I can't use the trick provided in this accepted answer because I would have to do cd path\to\my\folder to get to the current directory. Unfortunately, I can't do this command because path\to\my\folder is in fact a UNC path (\\path\to\my\folder), and cd \\some\UNC\path is not supported by the windows cmd.
I am aware of this answer but I don't want to use a temporary file.
So I tried to do the following:
To obtain the number of folders, I use:
dir \\path\to\my\folder | find /c "<REP>"
This works fine and returning me a number as I would expect.
To retrieve the output of this command in a batch variable, I tried:
FOR /F "TOKENS=*" %%i IN ('\\path\to\my\folder | find /c "<REP>"') DO
SET value = %%i
But without success, the error message being...
| was unexpected.
...when I execute the batch file and...
%%i was unexpected.
when I try to execute the command directly in a command window. I tried to escape the quotes around the <REP> string (...find /c ""<REP>""') DO...), got me the same error.
Am I on the right path to retrieve the output in a variable? What should I do to resolve the error message?
Or maybe there is a simpler way to set a command output in a variable?
You can use the answer you first mentioned. You don't have to cd there, but you can use pushd which will allocate a temporary drive letter for UNC paths which will be released when you do a popd.
So in essence:
pushd \\server\path
set count=0
for /d %%x in (*) do set /a count+=1
popd