I am trying to create a batch to automate commands for something. Right now I am just running a single command and the batch closes right after it prints the output from the command. I put a PAUSE in at the end but it keeps running past it. This is probably something very simple that I am just missing.
#echo
set /p ticket="Enter ticket number: "
tkt get %ticket%
PAUSE
The tkt get %ticket% part is from a custom utility I am using. That part is definitely formatted properly because I use it through command prompt every day almost. I want to automate a lot of my normal commands to make life easier.
Is "tkt" a batch file? Try making it "call tkt" instead.
If you call a batch file from another, the first one will exit after executing the 2nd one, unless it is called with "call".
Here's an example:
Foo1.bat
foo2.bat
echo foo1
Foo2.bat
echo foo2
It seems like if you run Foo1.bat, it will spit out both "foo1" and "foo2" but it does not:
C:\temp>foo1
C:\temp>foo2.bat
C:\temp>echo foo2
foo2
To change the behavior, Foo1.bat should look like this:
foo1.bat
call foo2.bat
echo foo1
Related
I have a batch file that copies and moves stuff, but I am getting stuck dealing with Certificates. I have to use a command the vendor provides called installrootcacert.cmd, but I also need to pass the file name of the cert which is aptly named rootca.cer. I have to use the script the vendor provides so there is no way around that.
Normally I would run this from the command like like so:
c:\vendor\Software\Conf\Security\installrootcacert.cmd rootca.cer
I have attempted to call the command from my batch file, but with no luck.
I tried to use a variable, but because that command calls several other processes, it is looking for "rootca.cer" after the command. If I place it in a variable, the other processes fail. I cannot modify the other processes.
echo #off
cd E:\vendor\Software\Conf\Security\trustedCA
e:
call "e:\vendor\Software\Conf\Security\installrootcacert.cmd rootCA.cer"
A possible solution, might be:
#echo off
cd /d "E:\vendor\Software\Conf\Security\trustedCA"
call "E:\vendor\Software\Conf\Security\installrootcacert.cmd" rootCA.cer
echo #off replaced with #echo off because echo #off will echo #off in cmd.
It is mentioned by Compo in comments, you are changing drives: use /d option with cd.
Finally, quote only the filename in the call command, else, windows will interpret this as a complete filename (i.e. E:\vendor\Software\Conf\Security\installrootcacert.cmd rootCA.cer, so filename will be installrootcacert.cmd rootCA.cer).
Try the following. You need to adjust the # in your echo statement and your quotations:
#echo off
cd E:\vendor\Software\Conf\Security\trustedCA
e:
call "e:\vendor\Software\Conf\Security\installrootcacert.cmd" rootCA.cer
The reason that this works is because putting the command #echo off in your script stops ALL commands from being output. If you just have echo #off, you're literally going to echo that. (credit to double-beep for initially suggesting that)
As for the quotes, what you are trying to do is pass that as a command, so when you call the rootCA.cer, you need to make sure you are passing it the proper parameters, which is why you place that filepath in quotes. If you place the WHOLE object in quotes, you aren't actually issuing a call to the rootCA.cer command. (credit to LotPings for initially suggesting that).
I have a Garry's Mod server I want it to autorestart every 12 hours. I can make a script where it executes a command every 12 hours but I dont know how to send the command "quit" to the process "srcds.exe". I saw something like
echo quit |srcds.exe
I tried it but it didnt work. How do I do this using MS-DOS (batch file)?
You are looking for the taskkill command:
taskkill /f /im srcds.exe
And it kill the tasks srcds.exe
If you can edit the program you want to send a command to, you can try inserting this command line into it where you want it to terminate:
if exist (directory)\(triggering file).txt del /Q (directory)\(triggering file).txt & quit
This will scan for the file that the triggering program will create, delete it, and then quit the program. If the file is not present, the program will ignore the line and move on as if the command line wasn't there.
The triggering program can be run whenever you want to terminate the main program. This program should be:
echo.>"(directory)\(triggering file).txt"
exit
Above was the simplest way of doing this. If you want to make it more "idiot proofed" you can add as the first line of the main program:
echo.>"(directory)\(main run file).txt"
This will write a .txt file the same way the triggering program does. This tells the triggering program that the main program is running and it can terminate it. You will also have to change the above IF statement in the main program to read:
if exist (directory)\(triggering file).txt del /Q (directory)\(main run file).txt & del /Q (directory)\(triggering file).txt & quit
Finally, change the triggering program to read:
if not exist (directory)\(main run file).txt quit
echo.>"(directory)\(triggering file).txt"
quit
Just some final notes, wherever I have "(directory)" replace it and the ()'s with an otherwise unused, untouched directory. Wherever you see "(triggering file)" replace it and the ()'s with a filename that is common with all other places you see "(triggering file)". Same goes to "(main run file)" but it must have a different name then "(triggering file)".
I know this might be confusing. Don't be afraid to comment and ask quesions. I will be happy to clarify.
Just like ipconfig, when typed in batch it executes a command, so how do I make a new command, without using CALL, and can be executed anywhere, not just that path.
So just like that this code-
#echo off
color fc
echo Example
echo :--:
pause
Can be executed by this command
EXEM
If you can help, thanks.
You can write your EXEM.BAT file as normal, then convert it to EXEM.EXE with something like this bat to exe converter.
You can then put it somewhere in your %Path% and it will run when running EXEM from CMD, without terminating execution.
Good luck!
If from inside a bat file you called another batch file but still had a few remaining operations to complete, how can you make sure that the call to first bat file will after completion or error, will return to the file that called it in the first instance?
Example:
CD:\MyFolder\MyFiles
Mybatfile.bat
Copy afile toHere
or
CD:\MyFolder\MyFiles
CALL Mybatfile.bat
COPY afile toHere
What is the difference between using CALL or START or none of them at all? Would this have any impact on whether it would return for the results of the copy command or not?
As others have said, CALL is the normal way to call another bat file within a .bat and return to the caller.
However, all batch file processing will cease (control will not return to the caller) if the CALLed batch file has a fatal syntax error, or if the CALLed script terminates with EXIT without the /B option.
You can guarantee control will return to the caller (as long as the console window remains open of course) if you execute the 2nd script via the CMD command.
cmd /c "calledFile.bat"
But this has a limitation that the environment variables set by the called batch will not be preserved upon return.
I'm not aware of a good solution to guarantee return in all cases and preserve environment changes.
If you really need to preserve variables while using CMD, then you can have the "called" script write the variable changes to a temp file, and then have the caller read the temp file and re-establish the variables.
call is necessary for .bat or .cmd files, else the control will not return to the caller.
For exe files it isn't required.
Start isn't the same as call, it creates a new cmd.exe instance, so it can run a called batch file asynchronosly
The `CALL' statement was introduced in MS-DOS 3.3
It is used to call other batch files within a batch file, without aborting the execution of the calling batch file, and using the same environment for both batch files.
So in your case the solution is to use CALL
Okay, I actually didn't even really think about the fact that if you call a batch (regardless of the 'type', i.e. '.bat', or '.cmd') that it won't return if you don't use call.
I've been using call myself though for a different reason that I am actually pretty surprised that no one else has brought up. Maybe I missed it. MAYBE I'M THE ONLY ONE IN THE WORLD WHO KNOWS!! :O
Probably not, but I'm going to drop this knowledge off here because it's super useful.
If you use call you can use binary logic operators to decide how to proceed based on the ERRORLEVEL result. In fact, I always was flabbergasted on how && and || existed in DOS and COULDN'T be used this way. Well, that's why.
The easiest way to test this is to create a return.cmd with notepad, or from the command prompt like so:
c:\> type con >return.cmd
You will now notice the cursor goes down to the next line and hangs. Enter:
#exit /B %1
And then hit ENTER, and then CTRL-Z and that file will be created. Good! You may now feel free to try the following two examples:
call return.cmd 0 && echo Huzzah! A Complete Success! (Or cover up...)
call return.cmd 123 || echo Oops! Something happened. You can check ERRORLEVEL if you want the tinest amount of additional information possible.
So what? Well, run them again with the 0 and the 123 swapped and you should see that the messages DON'T print.
Maybe this multi-line example will make more sense. I use this all the time:
call return.cmd 0 && #(
echo Batch says it completed successfully^^!
) || #(
echo Batch completed, but returned a 'falsey' value of sort.
call echo The specific value returned was: %ERRORLEVEL%
)
(Note the 'call' in the || section before the second 'echo'. I believe this is how people got around not having delayed expansion back in the day. If you DO have delayed expansion enabled (via. setlocal EnableDelayedExpansion inside a batch OR launch a command prompt with cmd /v:on then you can just do !ERRORLEVEL!.)
... This is where I have to apologize and say if you have if ERRORLEVEL trauma in your past you should stop reading. I get it. Trust me. I thought about paying someone on fiverr to remotely type this for me, but for completeness sake I'm just going to take one for the team and mention that you can also do the following to check errorlevel:
if ERRORLEVEL 123 #echo QUICK! MOTHERS, COVER YOUR CHILDREN'S EYES! FINGERS ARE BEING UNDONE! :'(
If you've never typed that before then GOOD! You will live longer without having to read up why exactly you aren't getting the results you expect. Cruel is the word you're looking for, not 'quirky'.
The important part that I really want to get across however is that if you try this and DON'T use 'call' it will ALWAYS execute the 'true' branch. Try it for yourself!
If I'm missing something, or you know a better way to do this, please let me know. I love learning stuff like this!
Additional information I mentioned:
I have known for quite some time that you can put redirects BEFORE commands like so:
>nul echo. This won't be displayed!
But I accidentally discovered the other day by being a dumdum that you can apparently also do:
echo A B>file.txt C
And was REALLY surprised to find a file.txt which consisted of "A B C". It appears yo can place them ANYWHERE, even inside the command. I've never seen anyone do this, nor mention it, but I HAVE seen people mention that you can prefix a line with them.
Maybe it's a bug exclusive to Windows 10 or something. If you have another version and wanna try it out and let me know I'd be interested in what you find out.
Stay nerdy!
I understand how to call nested batch files from within a parent file using the call command, as there are plenty of resources on that:
CALL
CALL (SS64)
Bat file termination
However, I don't understand why calling another batch file from another terminates the parent.
For a less abstract example, suppose I have a batch file that "links" together separate batch files, and I erroneously didn't prepend call to each line:
foo.bat
bar.bat
This would only execute foo.bat and then exit. To correctly execute both commands, I would have to prepend call before each statement:
call foo.bat
call bar.bat
Why does the first functionality still exist? Why hasn't it been changed? I noticed that call was introduced in MS-DOS 3.3, which was released in the late 1980s, so is this functionality still here for reverse compatibility?
I can't think of any (practical) usages of it, but perhaps I'm too used to "new" programming techniques.
DOS used simple text processing (back when you had things like FILES=20 in config.sys to allow 20 file handles), so opened the file, read the next line, closed the file, then executed the line just read. If the file called another, then the processing continued with that file, so only 1 file handle would be required for a batch file.
Until Microsoft put in the call command, there was no way to get back to the original file (without using tricks like giving the name of the previous file as a parameter, and using temporary files to let the original batch file know it had dome some processing, and could then GOTO the next part of the file).
As Sean Cheshire wrote, it's necessary for backward compatibility.
But starting a batch file from a batch file without using CALL does not terminate the parent!
It looks that way, as the parent normally will not executed further after the second batch exits.
But using a call before starting the second.bat, will show that the first batch isn't terminated.
parent.bat
echo parent.bat
call :myLabel
echo back in parent.bat main
exit /b
:myLabel
second.bat & echo back in parent.bat
exit /b
second.bat
echo second.bat
exit /b
I use here the the secpond.bat & echo back ... to avoid another bug/feature of cmd.exe.
If you use second.bat without any extras it will start second.bat AND jump to the label :myLabel in second.bat!
Call is basically saying "go execute this other batch file, and then come back here and continue". It has been there since DOS 3.3 or so, and if it were removed now would break all backward-compatibility (which is why people are still using batch scripts). It can also be used to branch to :link locations.
For info on the use and syntax (for future reference for others), you can see this MS TechNet link
If you need new functionality, use CMD scripts or PowerShell scripts instead.