I have written a shell script to execute a series of commands. One of the commands in the shell script is to launch an application. However, I do not know how to continue running the shell script after I have launched the application.
For example:
...
cp somedir/somefile .
./application
rm -rf somefile
Once I launched the application with "./application" I am no longer able to continue running the "rm -rf somefile" command, but I really need to remove the file from the directory.
Anyone have any ideas how to compete running the "rm -rf" command after launching the application?
Thanks
As pointed out by others, you can background the application (man bash 'job control', e.g.).
Also, you can use the wait builtin to explicitely await the background jobs later:
./application &
echo doing some more work
wait # wait for background jobs to complete
echo application has finished
You should really read the man pages and bash help for more details, as always:
http://unixhelp.ed.ac.uk/CGI/man-cgi?sh
http://www.gnu.org/s/bash/manual/bash.html#Job-Control-Builtins
Start the application in the background, this way the shell is not going to wait for it to terminate and will execute the consequent commands right after starting the application:
./application &
In the meantime, you can check the background jobs by using the jobs command and wait on them via wait and their ID. For example:
$ sleep 100 &
[1] 2098
$ jobs
[1]+ Running sleep 100 &
$ wait %1
put the started process to background:
./application &
You need to start the command in the background using '&' and maybe even nohup.
nohup ./application > log.out 2>&1
Related
I have little experiences in shell commands in unix.
So far, I have checked stackOverflow and know how to run simple shell scripts in order by
using echo
echo $(sh dosomthing1.sh)
echo $(sh dosomthing2.sh)
directly using sh xxx and wait
sh dosomthing1.sh
wait
sh dosomthing2.sh
using &&
sh dosomthing1.sh && sh dosomthing2.sh
But these ways seem to be helpless to solve my problem...
Here is my problem:
I have a basic shell script to do a maven compile and then using "nohup xxx &" to start a java application in background. the script is shown below:
#get the input env parameter
env=$1
#goto application root directory
cd /applicationDir
#to compile
mvn install -Dmaven.test.skip=true
#to start with parameter env
nohup java -jar -Dspring.profiles.active=$env myApplication.jar &
#to tail the log
tail -20f myApplication.log
I have too many different applications with the same startup scripts and it is hard to start them one by one. I need to start them with one command.
All the shell scripts are expected to be processed one by one in order. If there are any exceptions, skip and run the next one.
And when I tried to write a script like this:
sh start1.sh
wait
echo "application 1 was start up"
sh start2.sh
wait
echo "application 2 was start up"
...
sh startxxx.sh
wait
echo "application xxx was start up"
Though all the children shell scripts will process in order as what I expected, and the output infomations looked like the shell is functioning well, but the fact is only the last application will be started, all the previous command "nohup xxxx &" will be shut down.
Also I have tried to write like this:
sh start1.sh &
sh start2.sh &
...
sh startxxx.sh &
Although the result was what I want, all the application will be started well, but during processing the scripts, because of the parallel running of the scripts, the consoled output is unreadable. It comes to a good result but not a graceful way.
I have no idea how to solve this problem...
Please help me with this, thank you very much!
When you have a script with commands, you cam do chmod +x start.sh. Now the script can be started with ./start.sh. You will avoid an additional sh process and with ls -l you can see which scripts are executable.
In your scripts you have tail -f. This will be very confusing for a backgound process. Start the scripts in the background and view the logging from the console. I do hope that each script is using a different myApplication.jar and myApplication.log.
When the logging in the logfile is duplicated in stdout (your commandline window), you can throw that logging away.
./start1.sh > /dev/null 2>&1 &
./start2.sh > /dev/null 2>&1 &
./startxxx.sh > /dev/null 2>&1 &
The processes will be killed when you logout before the scripts are terminated. This can be avoided with nohup:
nohup ./start1.sh > /dev/null 2>&1 &
nohup ./start2.sh > /dev/null 2>&1 &
nohup ./startxxx.sh > /dev/null 2>&1 &
Edit:
OPS wants to start programs in a fixed order.
Starting scripts exactly one after another in order, should be possible by calling them in the right order (perhaps with an additional sleep 1).
When you need to wait for program 1 finished some init stuff, you need to check that. Use 1 script calling all scripts and add some control statements, like
nohup java something &
while ! grep -q "Started" myApplication.log; do
sleep 1
done
When the java program has an error the while will wait for ever, so replace this with some max retrycount
for ((retry=0l retry<100; retry++)); do
grep -q "Started" myApplication.log && break
sleep 1
done
https://man7.org/linux/man-pages/man8/cron.8.html
This might help you. Cron is a task scheduler, which you can use to run programs in sequence. If the man page is difficult to understand, look for tutorials on it; I'm sure some would exist.
I write a simple bash script:
while :
do
sleep 2;
//my code
done
Now I want this bash script always be running.
bash mybash.sh > /dev/null &
When I run above command my bash works fine. but when I close my terminal I think my bash is killed. because it doesn't work as my script make some files when it running.
Run the script "bash script.sh" in terminal and press ctrl+z and then use 'bg' command to put the script in background
#!/bin/bash
while true; do
// your code
sleep 5;
done;
write a bash script and put it that to cron and check once it will start comment the cron it will run in a background.
insted of sleep 5 you can use whatever second you want to put.
For checking your process use below commend to get the details
ps -ef | grep script_file_name
if you find more then one process is running leave one process and rest kill the process for script.
Hope so this will resolve your issue....!!!!
I have a script that looks like this:
pushd .
nohup java -jar test/selenium-server.jar > /dev/null 2>&1 &
cd web/code/protected/tests/
phpunit functional/
popd
The selenium servers needs to be running for the tests, however after the phpunit command finishes I'd like to kill the selenium-server that was running.
How can I do this?
You can probably save the PID of the process in a variable, then use the kill command to kill it.
pushd .
nohup java -jar test/selenium-server.jar > /dev/null 2>&1 &
serverPID=$!
cd web/code/protected/tests/
phpunit functional/
kill $serverPID
popd
I haven't tested it myself, I'd like to write it on a comment, but not enough reputation yet :)
When the script is excecuted a new shell instance is created. Which means that the jobs in the new script would not list any jobs running in the parent shell.
Since the selenium-server server is the only background process that is created in the new script it can be killed using
#The first job
kill %1
Or
#The last job Same as the first one
kill %-
As long as you don't launch any other process in the background - which you don't - you can use $! directly:
pushd .
nohup java -jar test/selenium-server.jar > /dev/null 2>&1 &
cd web/code/protected/tests/
phpunit functional/
kill $!
popd
I want to run the script every 30 minutes with cron but I have problem with my code.
In every 30 min I have to kill old script and run it again. I have somethink like this, but it is not working:
cd /var/www/scripts
pkill -f bot
now="$(date +%Y%m%d%H%M%S)"
screen -S bot
node mybot.js >> logi/logi_$now.txt
You may not use screen for running things in background in a script. Use ampersand (&) to background a process and nohup so it won't be killed when cron script exits. Also remember a subprocess PID in a file.
Something like this:
kill -- "$(cat mybot.pid)"
now="$(date +%Y%m%d%H%M%S)"
nohup node mybot.js >> "logi/logi_$now.txt" &
echo $! > mybot.pid
use crontab :
crontab -l
*/30 * * * * /path/to/your/command
save and run
The line
node mybot.js >> logi/logi_$now.txt
is never reached, as screen -S <session name> will start a screen session and therefore a new shell and connect to it. The rest of the script would only execute once that 'inner' session terminates.
screen is more for interactive use. Calling it in a script like this is rather strange. I guess you want to have node mybot.js >> logi/logi_$now.txt running in the background, so that your script can terminate while node keeps running. See Redirecting stdout & stderr from background process and Node.js as a background service for options how to do that.
I want to run a command silently via ssh and exit the shell, but the program should continue running.
I tried screen and nohup, but apparently with those it executes 3 processes instead of 1:
user:/bin/bash ./[script]
root: sudo [commandInTheScript]
root: [commandInTheScript]
What am I doing wrong?
P.S.: The thing is that I want to run this command with the Workflow app (iOS), but the app waits until the command is finished, so it freezes 'forever'
To run your process back ground, at end of the command you have to use &.
In your case, you have to run without session since you are planning to exit from ssh after execute the command, so you need nohup
nohup <command> &
nohup < command > &
This makes your command runs on background and shows its PID
How did you use nohup?
Eg.
nohup ruby server.rb &
Ampersand (&) is necessary to let command run in the background.