BATCH - wait for executable to finish before starting next result - batch-file

I'm pretty much a noob at this, so any help is appreciated.
I'm trying to run the video transcoding executable REDline on all .R3D files in a given folder. REDline only accepts single files, which is the issue. I finally got it to search recursively for the files I need, but my problem is the search function passes the next result to REDline before the first one is finished transcoding. I have the search results that need to run in a variable inside REDline.
Here's the code:
for /r D:\folder\ %%a in (*) do (
"C:/Program Files/REDCINE-X PRO 64-bit/REDLine.exe" --exportPreset "Prores_Intermediate" --i "%%~dpnxa" --useRSX 2 --masterRMDFolder "" -s 0 -e 95
)
After about .7 seconds, REDline reports 'received stop message from client'.
I don't think this is a REDline error, as I have been able to transcode single files successfully.
Thanks.

Try start /wait when running the executable.
If that does not help, the executable might start another executable which does the actual job. In that case identify the other executable using Process Monitor or Process Explorer. Check their command line parameter to see if you can run that executable directly.
If you can't run the other process yourself, you can wait until that process has exited. See Wait for executable to finish here on StackOverflow.

Im not familiar with that particular executable, but here are some suggestions you may try:
- Check the allowed parameters for REDLine.exe (documentation or possibly /?) to find out if there is any that might address your problem
- There are tools that allow you to check for the existance of a process (Microsoft Sysinternals, check the ones starting with PS*.exe) http://technet.microsoft.com/de-de/sysinternals/bb545021.aspx
Use this to improve your loop so that you check if the process is running first before continuing with the next loop - or loop without doing anything until the process has exited, you can do with repeatedly calling a ping to localhost inside your loop for a fixed time interval for example
- Check the errorcodes returned by programs to see if that helps you
- Put the code that starts your encoding inside its own batch file, and the check if the process is currently running as well
- Use the creation of a dummy file before starting and delete it once finished to discern if an instance of your batch is running
- Check the difference between calling a command directly from a batch file, and using the start command to run it at the same time

Related

Use environment variable set by a batch script in the next batch script run

Actually i want to run 2 bat scripts , first script will set a system variable set NEWPATH="E:/Some" and second script will show the path of that variable: echo %NEWPATH%. this is not working with the same server at first time , when i restart server that will show the path otherwise it'll show nothing. so can anyone help me on that?
I don't fully grasp your problem, but here's a couple of observations.
Some theory
Environment vaiables set in a batch file (which is being executed by a shell process, cmd.exe)—or any other kind of process—can only be set for that very process.
That is, each process has a special block with environment variables made available to it by the OS when that process is created.
This also means that when the process which set an environment variable is finished, it's environment block is gone.
An environment variable can be inherited by a process which was started by the process which has set that environment variable.
What happens in your case
What this means is that if you run two batch scripts in a sequence, this means
The first cmd.exe process is strated, the batch script it executed
set an environment variable; then the process is gone, and its environment block is gone, too.
Then another cmd.exe is started, it inherits the environment block of your host process (written Go), but as you can see, whatever is set by a first batch script is not available.
What you can do about it
There are two possible ways to solve the problem:
Make the first batch script call the second one by itself.
In this case the second cmd.exe will inherit the environment variables
set by the first script and will hence "see" them.
Note that the Windows batch command language supports the calls
command to call out to other batch scripts by their pathnames.
Make the first script communicate the value of that variable to your host process and then arrange in the host process for the second cmd.exe to have the indicated variable with the indicated value in its environment.
Say, the first script could just do something like
echo VARNAME=value
to have
VARNAME=value
printed to its stdout.
Your Go process could parse that output, tear it apart on the =
character, sanitize to not affect "interesting" variables like PATH,
USERPROFILE etc, and then the host process could do
env := os.Environ()
env = env.append("VARNAME=value") // real value here
...
cmd := exec.Command(`cmd.exe`, `/c`, secondScriptFilePath)
cmd.Env = env
...
cmd.Run() // or whatever
The second case can be done a bit differently: the host process
can call os.Setenv("VARNAME=value") to make this variable appear in its
own environment block; it then will be inherited automatically by whatever processes it starts after that.
Update to address the OP's comment
…script files will be in client side so i can't add a line
echo VARNAME=value .
so is there any other possible way to do this?
There's another approach which might work in your case.
The idea is that cmd.exe is just a shell: when it's started non-interactively (that's what is done by exec.Command("cmd.exe"))
it reads commands from its standard input stream and executes them one by one—until the stream is closed (by the sender).
Hence you can do the following:
Start cmd.exe while connecting an instance of io.Pipe to its Stdin.
Open the first script yourself and shovel it at the running cmd.exe via the pipe set up on the first step.
Don't forget to Flush() the pipe.
You can use the io.Copy() function which sends all the data from an opened io.Reader to some io.Writer.
Leave the shell instance running.
When it's time, read the second script and shovel it at the same shell.
Since the shell is the same, the second script would run as if it were physically appended to the first one, and will see all the variables set by the first script.

Run c shell skripts within shell skript and wait until jobs are completed

I want to call several C shell scripts within one master script one after another.
Since a previous batch script creates files which the following script needs, I have to wait until the first script has successfully terminated.
How do I implement the query whether the previous script is still running or has already stopped?
thanks a lot!
ok I figured it out:
#!/bin/csh
csh 1_script.sh
set pid1=$!
csh 2_script.sh
set pid2=$!
wait $pid1
wait $pid2

Spawning multiple copies of a program from C code and redirecting the output to a file

I am working on modifying a command-line program that is written in MSDN C and Pro*C (Oracle pre-compiler to write in-line SQL and PL/SQL statements) so that multiple copies can be spawned and process concurrently. It is a database-heavy program and concurrency issues are mostly taken care of on the database side, so we thought it would be easier to just run multiple copies than to alter the program to run truly multi-threaded.
Anyway, we rely on printf() and output piping to write the program's output to log files for debugging purposes. I am having trouble launching separate copies of the exe that appropriately write to their own log files. I have played a lot the exec() and system() functions to get different copies of the EXE to launch and write to logs. The closest I have gotten to work is using a C line such as:
system("start cmd /k call [program commmand and args] > log_file.txt");
This works great - spawns separate command windows and spawns separate copies of the program for the appropriate data-sets. The only problem is that the command windows stay open after the program has finished executing. Some of our clients run this program frequently on a scheduler, and having to manually close all of the command windows would not be acceptable for them.
Other similar commands that I have tried to get to what I am looking for are like:
system("[program command and args] > log_file.txt");
or
exec("[program command and args] > log_file.txt");
Both of these will execute a new copy of the program, write to the log files just fine, and close the command window when the process is finished, but the commands wait for the newly spawned EXE to finish running to return control to the launching executable. This obviously prevents multiple copies from running at the same time, which was the whole goal to begin with, so this is not a good solution either.
I also played with trying to add an "exit" command to the end of the command line windows by appending to the exiting command line, hoping that I could get the command window to close, like this:
system("start cmd /k call \"[program commmand and args] > log_file.txt; exit\"");
to no avail. I tried some similar variations, but could never the correct behavior.
I would greatly appreciate any advice that could get the correct behavior. I am basically looking to launch multiple copies of an executable that run concurrently and write to separate log files, using the " > log_file.txt" output-piping feature of the windows command prompt. I would like to avoid having to use threading libraries (It's been awhile and I'm under time constraints) or using something other than printf() and output piping, since these print statements are used throughout the application and it would be a large effort to effectively replace all of the function calls at this point in time.
Anyone know a way to get the command windows to close using system() calls, or have some other easy method of solving the problem? Keep in mind that there are some time constraints involved, so I'm not necessarily looking for the best way to do this, but the quickest and easiest. I will have the opportunity to implement proper logging functionality soon, but I need to get past this problem first.
You said your first solution works great except it doesn't close the command window after the program is done executing.
system("start cmd /k call [program commmand and args] > log_file.txt");
The /K option states Carries out the command specified by string but remains
The /C option states Carries out the command specified by string and then terminates
You should be able to change your original solution to use the /C option as so
system("start cmd /C call [program commmand and args] > log_file.txt");

Ensuring application close in batch files

Specifically, I'm using DGIndex in a batch file as part of a sequence to do some video encoding.
Despite accepting CLI params, DGIndex pops up a window to do the processing. This then disappears when it's finished, but the command line hangs as though it's still open. The process is no longer running.
Is there something built-in that I can do to ensure it doesn't hang, or is there a third-party proxy utility that will monitor for a process end then close itself?
I had the same problem with DGIndex in batch files. I know this is an old question, but it seems DGIndex hasn't been updated since then, so this might still be relevant.
DGIndex has 2 different command-line "styles", in the manual one being called legacy (the one using upper case letters for the settings), the other UNIX-style (lower case letters).
For me, the "-exit" command of the UNIX-style command-line did not work, so that the batch file did not receive a corresponding message from DGIndex, even though it finished its job correctly. I used the legacy commands instead, and the problem was gone.
"Funny" that Dan had the problem with the legacy commands, so the other way round.
Regards, Mike.
You could use something like this:
#echo off
echo Running program
start dgindex -BF=[vob.txt] -FO=0 -IA=2 -OM=2 -TN=0 -OF=[out] -HIDE -EXIT
ping 127.0.0.1 -n 10
taskkill /im dgindex.exe /f
exit >nul
This batch file basically runs the DGIndex program and then pauses for 10 seconds before attempting to close the program. Just replace the 10 with a delay of your choice, something long enough that if the program is still running it means it's crashed, then it will be closed after the delay.
I'm pretty sure you can't tell if the program has hung or not (at least not in batch anyways). This at least makes sure it isn't running if you need to run it again if it did crash.
Hope this helps!
If you use start, the batch file should return immediately after starting the dgindex application.
You can pass the /WAIT flag to start to it to tell it to wait until the process has exited before moving to the next line of the batch file.
start /WAIT dgindex -BF=[vob.txt] -FO=0 -IA=2 -OM=2 -TN=0 -OF=[out] -HIDE -EXIT
I know this is old, but did you ever get it figured out?

Batch file stops running after the first command

I am using the tool 'HTML Match' to compare two HTML files. As I have to compare many files, I create a batch file like the followion. For example, I give only five sets of files.
cd "C:\Program Files\HTML Match"
HTMLMATCH.EXE "D:\Raj\compare1\a1.html" "D:\Raj\compare2\a1.html" "D:\Raj\compare_res\a1.html"
HTMLMATCH.EXE "D:\Raj\compare1\a2.html" "D:\Raj\compare2\a2.html" "D:\Raj\compare_res\a2.html"
HTMLMATCH.EXE "D:\Raj\compare1\a3.html" "D:\Raj\compare2\a3.html" "D:\Raj\compare_res\a3.html"
HTMLMATCH.EXE "D:\Raj\compare1\a4.html" "D:\Raj\compare2\a4.html" "D:\Raj\compare_res\a4.html"
HTMLMATCH.EXE "D:\Raj\compare1\a5.html" "D:\Raj\compare2\a5.html" "D:\Raj\compare_res\a5.html"
When I execute this batch file in a cmd prompt, only the first line, that is, only 'a1.html', gets compared and produces a result. Then execution stops.
Add call in front of the commands you're running.
You can also change this to a for loop, so:
FOR /L %%i in (1,1,5) DO CALL HTMLMATCH.EXE D:\Raj\compare%%i%%\a%%i%%.html D:\Raj\compare%%i%%\a%%i%%.html D:\Raj\compare_res\a%%i%%.html
The answer to your problem is to write CALL HTMLMATCH.EXE (and the rest of the parameters).
Just use CALL in front of every executable command in the batch file.
I was looking for something really similar and tried, I think, all the replies left here but I finally found the solution to my problem!!
In my script I want to check if one process is running, if not, start it (a .exe) and then check if another process is running, if not, start it too (but leave all the programs opened) and the problem is that the first .exe was started but then not moving to the second one because it was waiting until the process ended.
It´s finally working for me with start and the magic comes with...
/separate
it works for me as:
start "program1" /separate program1.exe
other commands
Before it stopped after starting program1 because it was waiting until it was closed, I think, but this was not going to happen because I wanted to leave it opened.
Now with the start /separate it continues with the other commands.
I found it in another forum but the thing is that it´s the manual, /separate is used to start in another memory space.
You don't have to insert quotation marks where there isn't any space mark between.
Try that:
HTMLMATCH.EXE D:\Raj\compare1\a1.html D:\Raj\compare2\a1.html D:\Raj\compare_res\a1.html
Maybe it will solve your issue.

Resources