I am trying to write a batch file that starts another batch file, waits for that batch file to complete its job, and then continue once that other batch file has exited. However, when I manually close the batch file launched by the first batch file, it comes up with a prompt saying:
^CTerminate batch job (Y/N)?
Is there a way to automatically select 'N', because it needs to delete some temporary files on exit.
Purpose/Premise of Script: To be able to remove a flash drive and lock the station (hence copying files to external source).
Summary of Script:
Program Copies files to %homedrive%
Program launches another script (one of the files copied to homedrive)
After that program quits, it deletes the copied files
Solutions Tried:
Different command switches inside of START /WAIT +/I +/B (Adding /I
or /B did not produce anything useful)
Using /C and /K switches after the START /WAIT program.bat +/C +/K
(had no affect)
Well, you could use echo n | program.bat to automatically respond n to ^CTerminate batch job (Y/N)?, but an easy way to fool this method is to hit and keep pressed [Ctrl]-C.
There simply is no reliable way to disable the interruption of any program (much less a batch file). What stops the user from just closing the window?
You would want a command like this:
start /wait program.bat|echo n>nul
">nul" will hide the "n" that shows up afterwards. But there doesn't seem to be a way to stop "^C" from showing up.
Related
I am very new to creating batch files.
I have to run a command, with an increasing file number e.g
c:>program.bat -propertyfile "1.property"
Right now, I have to type the command manually, wait 1 minute, then type the command again by increasing the property file # i.e "2.property" "3.property" "4.property" etc....
I want to automate this, and still would like to see the results in the command prompt as it runs.
How can this be accomplished?
See https://ss64.com/nt/for.html and specifically https://ss64.com/nt/for_l.html
FOR /L %%G IN (1,1,4) DO program.bat -propertyfile "%%G.property"
Should run your command for files 1.property to 4.property but if you're actually running it for files in a directory rather than a list of integers one of the other FOR constructs might be more appropriate. Perhaps https://ss64.com/nt/for_r.html
Process Tree:
I have an MS Access version control macro that checks users current file version on open, and if not up-to-date, the macro launches a batch file that 1) should delete their current file, and then 2) copies the up-to-date front-end version from the network and pastes it on their local system.
My issue:
Everything works EXCEPT for the deletion of the users original file. Since this file is the parent process of the batch file I haven't found a way to Kill the task so it can be deleted.
Current Code:
TASKKILL /F /fi /IM MSACCESS.EXE /T
del "%originalFile%"
**I thought maybe I was having issues because the batch was a child of the Access process, so I've also tried with no luck:
TASKKILL /F /fi /IM MSACCESS.EXE
I always get the error:
ERROR: Invalid syntax. Value expected for '/fi'.
Its been a long day, so I assume I'm missing something simple and would love an extra set of eyes. Any help would be greatly appreciated!
I have a similar setup, but without TASKKILL.
Directly after launching my update batch, I do Application.Quit
' If need to update
Shell UPDATE_BATCH, vbNormalFocus
Application.Quit
And in the update batch, I wait for 3 seconds so that Access has enough time to exit (and release the lock on the frontend).
sleep.exe 3
REM ... copy new frontend ...
sleep.exe 1
REM ... start MSACCESS command line ...
How to "sleep"? See here: SLEEP.exe (2003 Resource Kit) for different variants.
I am trying a bit of experiments with airmon-ng script in Linux. Meanwhile i want to redirect output of a process "airodump-ng mon0" to a file. I can see the instantaneous output on the screen. The feature of this process is that it won't stop execution(actually it is a script to scan for AP and clients, it will keep on scanning) unless we use ctrl+c.
Whenever i try
airodump-ng mon0 > file.txt
i won't get the output in the file.
My primary assumption is that the shell will write it to the file only after completing the execution. But in the above case i stopped the execution(as the execution won't complete).
So to generalize i can't pipe the output of a running process to a file. How can i do that?
Or is there any alternative way to stop the execution of the process(for example after 5 seconds) and redirect the current output to a file?
A process may send output to standard output or standard error to get it to the terminal. Generally, the former is for information and the latter for errors, but in some cases, a process may mix them up.
I'm supposing that in your case, the standard error is being used. To get both of these to the output file, you can use:
airmon-ng mon0 > file.txt 2>&1
This says to send standard output to file.txt and to reroute 2 (which is the file id for standard error) into 1 (the file id for standard output) so that it also goes to the file.
I have a shell script which asks for user input and depending on the input opens db connection using sqlplus and run some sql querys like drop table /create table/select/update. Is it possible that the sql part be run as background job,so that even if i lose vpn connectivity to the network,all the sql queries gets executed.
Also ,when the sql parts gets completed and user is prompted with another input the shell script comes to foreground and after getting the input again goes to background?
I have found some questions which tell us how to run the script in background,but i want to run ONLY some parts of the same script in background if possible(and come to foreground for user input).Though i can make multiple scripts too handle it(dividing the scripts in parts which needs to be called in background and calling them though another script),i would rather do it in a single script if possible.
You can break your main script up into functions / smaller scripts to achieve the desired behavior of a mix of background processes and foreground processes.
For example, in your main script:
#!/bin/sh
echo "Starting script..."
# do so more stuff here, maybe ask user for input
./run_background_process_1 &
# ask the user for some more input
./run_background_process_2 &
...
Use the & symbol at the end of script calls to denote that they should be run in the background.
(Updated) If you'd like to keep everything in 1 script, use functions to break up / encapsulate the parts of logic that you would like to run in the background. Call these functions by suffixing the call with &, same as above.
You can try the following example to see that it works:
#!/bin/sh
hello() {
condition="yes"
while [[ $condition== "yes" ]]
do
echo "."
sleep 1
done
}
# Script main starts here
echo "Start"
hello &
echo "Finish"
Remove the & after hello and you'll see that it behaves differently.
There are tools which allow you to keep scripts running despite loss of connection. For example, check out http://www.gnu.org/software/screen/ - one of its features is Programs continue to run when their window is currently not visible and even when the whole screen session is detached from the users terminal.
After search on internet i found out i can use three methods to make the script background :
1) using bg: How do I put an already-running process under nohup? .but unfortunately ,this didnt worked for me in ksh shell.
2) using coprocesses
3) using nohup
I decided to go with nohup as it was easier to implement. The sqlplus part which needed to be run in background ,i made another script of it and called it from the main script using nohup
nohup script-name.ksh ${parameter1} ${paramter2} &
This worked for me.
I have a section of code;
:check
for /f "tokens=1* delims==" %%A in ('"wmic process get description, commandline /format:list"') do (
if "%%A"=="CommandLine" (
set "cmd=%%B"
) else if "%%A"=="Description" (
set "desc=%%B"
setlocal enableDelayedExpansion
set "desc=!desc:~0,-1!"
set "cmd=!cmd:~0,-1!"
if /i !desc! == %1 (
echo !cmd! >>C:\test.txt
)
endlocal
)
)
goto:eof
Which pretty much works (this is actually a function called from withing a batch file e.g
call:check processname1.exe
call:check processname2.exe
call:check processname3.exe
etc...
What I'd like to do (if possible), is, insead of echoing to a file, I'd like to be able to create 2 variables. something like;
processname1.exe processname3.exe <-- (for each process 'checked' if it IS running, append its name to this variable)
commandlinepath1 commandlinepath2 <-- (for each process 'checked' if it IS running, append its path to this variable)
If this is possible, and I can then call on these variable later in my script, I'd like to be able to tskill the running processes (easy enough if the variables above can be made), then later on, RE-OPEN these processes (using and command line parameter that were in the original path. This is where I'm lost.
My code above (writing to a file). will give results like;
"C:\somefolder\someexe.exe" -some_parameter
"C:\some therfolder\someotherexe.exe"
"C:\another older\anotherexe.exe" param1 param2
But What I need to do, is take each line of this file (or variable if possible), and run them (if I copy each line into the RUN command of windows, it works, but doing it through CMD it doesn't).
I've tried using a for loop to open the files, and it does, except the script waits for the process to finish beford continuing (and these process won't end, since they are applications). If I try to use START .. then it loads a new CMD window??
What I need to do (in case there is a better option) is
for a pre-determined set of processes, check to see if they are running
kill the ones that are (if they are not, fine ignore it)
delete some files (I can do this, the reason for killin the processes is they hold the files open, preventing deletion)
Re-open all the programs that were originally running
Thanks..
Not a direct answer, but since you already use wmic, maybe using its built in capabilities (query, start & stop) would make your goal easier to achieve?
I come up with the following:
#echo off
setlocal
for %%C in (notepad.exe) do (
for /f "skip=1 tokens=2 delims==" %%F in ('wmic process where description^="%%C" get commandline /format:list') do (
REM required to normalize unicode output from WMIC
set commandline=%%F
REM '\=\\' required as wmic treats \ as escape char in query
call wmic process where commandline='%%commandline:\=\\%%' terminate
REM do your work here
call wmic process call create '%%commandline%%'
)
)
What it does:
First for supplies process names. In my example, it simply is notepad.exe, but you could call with a list: for (process1 process2 process3), or replace it with for /f to supply values from file. If you want to use quoted names, you would have to remove quote from next line (description^="%%C").
Second for does real work: it gets a list of all processes matching description and sequentially stops and starts each of them.
To try it, simply put it in a batfile.bat, open notepad(s) and execute.
Note: if you open notepad with a file, either specify an absolute path, or do it via explorer (double click). The issue here is of current directory - which you could also stumble upon if any of your processes does reference relative paths (unlikely, but not impossible)
Last but not least - doing that in powershell would be the easiest, shortest and most reliable.