I'm writing a script that performs the same function several times, but when I run the script only one of commands executes leaving the rest not executed after the .bat file has run.
Does this have to do with the long time it takes for my commands to run (15-20 sec)? I've written plenty of bat files and I've never run into this. Do I need to have a sleep function between each command?
I've been trying to figure this one out on google, but my available search terms makes my search results vague and difficult.
Any help is definitely appreciated.
the bat file looks something like the following
IF input1 == "search term" goto location
do something
do something
do something
etc
goto end of file
:location
do something else
do something else
do something else
...
Does one of your "do something else" lines involve calling another batch file? If so, do you use the CALL command?
If you want to call another batch file recursively, you need to use CALL. Otherwise, when the called batch file exits, it does not return to the calling batch file and simply exits. This is a relic from the MS-DOS days; since memory was at a premium, the MS developers decided that the batch interpreter shouldn't keep a call stack by default -- so if you wanted one, you had to use CALL.
See call /? for more information.
Related
I have some init commands in a m-file on disk. Depending on where the user is executing from, the contents of that init file will will change.
I'm wondering if there is a way to have Matlab automatically call this init script every time a script begins execution (either via the Run key or by requesting a call to a function in the interpreter).
I've looked at the startup.m script and that won't work as it is only executed when Matlab is first started but I want something that runs each time a script begins execution.
I've also thought about placing some boilerplate code at the top of the script file, but, that doesn't work in cell mode as the script may start execution part way through the script which would skip the boilerplate code.
I have 8 scripts in Powershell which I run one by one. Let's call the scripts: script1.bat, script2.bat, .., script8.bat.
Now I need a script which runs all scripts.bat one by one, but not simultaneously.
And is there a way to check, if each script was successful?
./script1.bat
./script2.bat
./script3.bat
...
You'll get the picture, I guess. This will run them in sequence. To determine whether they were sucessful or not that depends very much on how those batch files signal errors or sucessful completion. If you exit with exit /b 234 or something similar on an error then you can use $LastExitCode or also $? to determine that. You could also look whether the changes made by those batch files are actually done, of there is no other way of figuring out whether they were sucessful.
Call CreateObject("WScript.Shell").Run(some.exe,0,False)
I'm using that line to call a .exe that returns some text, but can also write it to a file.
I would use .Exec instead of .Run to get the results directly but then the script hangs.
I really don't want a timer checking if the output file is created or modified.
What I need is a way to catch an event somehow. Any Ideas?
Since you mention that it might either return it or write it to a file, does that mean that after the process has written to the file it'll exit?
If so, you could just call the Shell.Run method with the bWaitOnReturn parameter set to True and your script would wait for the process to finish before it continued.
Otherwise, if the process might write a file and then still continue to run, then I think you will have to poll to check if it exists, or possibly you could create a C# or VB.Net exe that uses FileSystemWatcher (or a normal Win32 exe that uses the API FindFirstChangeNotification) to look for the creation of the file and when it finds one it immediately exists and then you could run that process with bWaitOnReturn set to True, but that's probably just overcomplicating things.
I have a quick question about creating files with perl and executing them. I wanted to know if it was possible to generate a file using perl (I actually need a .bat script) and then execute this file internally to the program. I know I can create files, and I have with perl, however, I'm wanting to do this internally to the program. So, what I want it to do is actually create a batch script internally to the program (no file is actually written to the disk, everything remains in memory, or the perl program), and then once it completes the writing of the file, I'd like to be able to actually execute this file, and then discard the file it just wrote. I'm basically trying to have it create a batch script on the fly, so that I can just have output text files from the output of the script, rather than creating the batch script on disk, then executing it, and then deleting the batch file from disk when its done.
Can this be done and how would I go about doing this?
Regards,
Drew
Do you really need a batch script? Perhaps everything you want to do can be done directly from Perl or invoked directly by Perl via its system command.
If a batch script is essential, what's wrong with creating a temporary file for the script and then executing it with system? See File::Temp, which will even delete the temporary file automatically after you are done.
If the virtual-batch-file strategy is unavoidable, you might be able to leverage the /C and maybe /S options of cmd. Something like this:
use strict;
use warnings;
my #batch_commands = (
'dir',
q{echo "Make sure quoting isn't busted"},
'ipconfig',
);
# Use & or &&, depending on your needs. Run `cmd /?` for details.
my $virtual_bat_file = join " &\n", #batch_commands;
system "cmd /C $virtual_bat_file";
But this feels very wrong. There has to be a better way to accomplish whatever the larger goal of your application is. By the way, when you run cmd /? to learn about /C, /S, and & vs. &&, you'll quickly appreciate how terrible it is in the Land of Batch. Stay away if at all possible.
open the file; create the contents; close the file; execute the file (with system(), for example); remove the file.
I have both Sybase and MSFT SQL Servers installed. There is a time when Sybase interferes with MS SQL because they have they have some overlapping commands.
So, I need two scripts:
A) When runs, script A backs up the current path, grabs all paths that contain sybase or SYBASE or SyBASE (you get the point) in them and move them all at the very end of the path, while preserving the order.
B) When it runs, script B restores the path from back-up.
Both script a and script b should affect the path immediately. So, if a.bat that calls patha.ps1, pathb.ps1 looks like so:
#REM Old path here
call patha.ps1
#REM At this point the effective path should be different.
call pathb.ps1
#REM Effective old path again
Please let me know if this does not make sense. I am not sure if call command is the best one to use.
I have never used P.S. before. I can try to formulate the same thing in Python (I know S.O. users tend to ask for "What have you tried so far"). Well, at this point I am VERY slow at writing anything in Power Shell language.
Please help.
First of all: call will be of no use here as you are apparently writing a batch file and PowerShell scripts have no association to run them by default. call is for batch files or subroutines.
Secondly, any PowerShell script you call from a batch file cannot change environment variables of the caller's environment. That's a fundamental property of how processes behave and since you are calling another process, this is never going to work.
I'm not so sure why you are even using a batch file here in the first place if you have PowerShell. You might just as well solve this in PowerShell completely.
However, what I get from your problem is that the best way to resolve this is probably the following: Create two batch files that each set the PATH appropriately. You can probably leave out both the MSSQL and Sybase paths from your usual PATH and add them solely in the batch files. Then create shortcuts to
cmd /k set_mssql_path.cmd
and
cmd /k set_sybase_path.cmd
each of which now is a shortcut to a shell to work with the appropriate database's tools. This is how the Visual Studio Command Prompt works and it's probably the cleanest solution you have. You can use the color and prompt commands in those batches to make the two different shells distinct so you always know what environment you have. For example the following two lines will color the console white on blue and set a prompt indicating MSSQL:
color 1f
prompt MSSQL$S$P$G
This can be quite handy, actually.
Generally, trying to rearrange the PATH environment variable isn't exactly easy. While you could trivially split at a ; this will fail for paths that itself contain a semicolon (and which need to be quoted then). Even in PowerShell this will take a while to get right so I think creating shortcuts specific to the tools is probably the nicest way to deal with this.