how to run a cmd.exe batch file in a sub shell - windows

I have a batch file that I usually invoke like this:
longjob.cmd >result.txt 2>&1
This works fine, but the script changes directory during its execution leaving my shell in that directory - which is a nuisance.
Is there a way to run the command within a sub-shell - while still allowing the output to be captured ?
I have tried
cmd longjob.cmd >result.txt 2>&1
which just sits waiting for an exit command.
Also I tried
start longjob.cmd >result.txt 2>&1
which does run the script, but in a new window and all output is sent to that window instead of the file.

Try
CMD /C longjob.cmd >result.txt 2>&1
Not sure how it'll deal with the redirection, but CMD /C lets you tell CMD what to run and that it should exit when done. (CMD /K lets you tell it to run something but stick around when done.) It will re-use the existing console window if run within one.

The call command might be what you want.
i.e.
call longjob.cmd >result.txt 2>&1

Related

Passing multiple commands to START command in batch file

I'm using start to run a command from a batch file.
SET mycmd=SOME_CMD WITH ARGS
START "Demo" %mycmd%
This works fine, and the resulting cmd window persists after executing the contents of mycmd, even if the batch file was double-clicked - the reason why I'm using start to begin with.
However I would also like to print something in the new cmd window that start opens, before it runs the command.
I'd imagine that I would pass start an echo command, followed by the command I want it to run.
My first naive approach was as follows:
SET mycmd=SOME_CMD WITH ARGS
START "Demo" ECHO Running Command... && %mycmd%
Of course this does not work; start opens a new window which only runs the echo command, and the command after the && divider is run in the original window, not in the new one that the echo ran in.
Basically it performs (start echo) && (my_cmd) instead of start (echo && my_cmd) - parentheses added for clarity, not any actual syntactic meaning
So my question is: Is there a way to pass two commands to start at once? Specifically, I really just want it to echo out some content, and then run a command.
Change && to ^& to escape a single & which then cascades the echo with your command.

Do I need "cmd /c"?

I've seen two different ways of calling icacls from VBScript:
oShell.Exec("icacls ...
or
oShell.Exec("%COMSPEC% /c Echo Y| icacls ...
What's the difference?
Usually you don't need to run it in a Command Prompt if it's an external command (executable, script, etc.). So if you can go to Start → Run… and run it from there, then you can run your application directly with all arguments, etc.
However, if you're using CMD builtin features, like internal commands (dir, echo, mklink, …), the pipe (|), or I/O redirection (>, >>, <), you must run the commandline in CMD, because otherwise these features wouldn't be available. The parameter /c is just to tell CMD to terminate after the command completes. It's not required, but it's good practice to put it there, so you can easily replace it with /k (keep CMD open after the command completes) for debugging purposes.
Have a look at the documentation for the /C switch using CMD /?.
The /C switch tells the cmd.exe program to return after it runs the specified command line. If it does not return, you will be left in a cmd shell. I do not know what this would look like from VBS.
My guess would be that, yes, you need /C.

Exit from cmd script that calls bash

I have the following cmd script which calls a cygwin bash script:
C:\cygwin\bin\bash -l /D/Temp/testScript/cygScript.sh
echo back in cmd.
exit
The bash script is simple:
#!/bin/bash
echo Hello World!
read
The calling part works nicely - the bash shell logs in, echos as expected, reads as expected and control passes back to the cmd as expected.
But the cmd will not exit. This is fine if I run it from a command window, but I will be calling this by double clicking on the cmd file or launching it from RUN etc.
Output I see:
D:\Temp\testScript>C:\cygwin\bin\bash -l /D/Temp/testScript/shellScript.sh
Hello World!
D:\Temp\testScript>echo back in cmd.
back in cmd.
D:\Temp\testScript>exit
How do I get the cmd to exit?
Found the problem - too many bashes
I think I found the issue - probably something in my .bashrc and other files I load during cygwin login. If I change the main cmd line to remove the login flag), it works as expected - everything closes.
C:\cygwin\bin\bash /D/Temp/testScript/cygScript.sh
But then I put the flag back:
C:\cygwin\bin\bash -l /D/Temp/testScript/cygScript.sh
and run again. I see the output Hello World! which shows me that control is with bash, and I check Task Manager. Four instances of bash.exe are created. Then I press ENTER and see the output back in cmd. showing me that control is back with cmd. Now Task Manager shows me that three bash.exe instances remain.
So, something in my login scripts are creating extra bash shells. So it's not you, it's me.
Avoid creating persistent subshells in login scripts by using cygstart instead of cmd.
Previously I wrote that the problem was too many bashes. My .bash_profile was doing something to create bash sub-shells (that were persistent because the jobs they launched kept going in the background). This meant that when my cmd created a bash (via login) and the first bash exited, the sub-shells didn't exit.
I found that part of my login scripts involved launching some Autohotkey scripts like this:
cmd /c "$thePath" &
The fix was so easy... just use cygstart:
cygstart "$thePath"

Batch file: How to redirect output from .exe with parameter?

I am trying to write a batch file to run a .exe with a parameter and that gives and output in .csv
I wrote:
start "" "C:\Users\Me\Desktop\AnalysisSoftware\Video.exe" S1.avi>S1.csv
This command is working but the created .csv file is empty. What's wrong?
I also tried with ^ like that:
start "" "C:\Users\Me\Desktop\AnalysisSoftware\Video.exe" S1.avi^>S1.csv
Not working too...
Thank you
Cec
The start command starts the command in another process and so the output is not captured, instead you are capturing the output of the start command, which is nothing.
What you need is
start "" "cmd /c C:\Users\Me\Desktop\AnalysisSoftware\Video.exe S1.avi>S1.csv"
The distinction here is that the redirection operator is within the quotes. In your example above the redirection operator was outside the quotes and so it captured the output of the start command instead of the Video.exe. Note you also need to use cmd /c at the beginning. This is because you need a shell in order to redirect the output of the Video.exe. The /c argument tells cmd to exit as soon as the command finishes executing.

execute user inputed Windows (or bash) commands from batch (or bash) file?

Ok, so I have this batch script and what I want to happen is that when you run the script it does some standard stuff like change the path and access files etc... but after it's done that it goes back to being a normal cmd prompt/terminal where I can type in commands at free will.
Can this be done (in either dos or bash)? Is there like an execute command that I can put in an internal while loop or is there a command where when the scirpt ends it can go back to the normal cmd/terminal?
Do you need a full bash prompt?
Or would something like this be enough?
#!/bin/bash
echo -n "Enter cmd: "
read COMMAND
echo ${COMMAND} | bash
Also, in a script, you can just execute bash and get a full prompt in the current environment.
In Dos / windows command prompt if you run the batch file from command line you will get the prompt back always by default. Just like running any other command in command prompt.
Also in windows when the batch file execution is complete you can just put Cmd.exe when everything has finished running I.e at the end of the batch file.
Hope this helps!
E.g
#echo off
Echo running
.
.
.
Cmd.exe
Or even at the end
Echo %command% | Cmd.exe
Never mind, I got a good solution using this code: (for windows)
set /p command=CMD:
%command%

Resources