Starting and stopping a process daily using the shell? - bash

I know I can start the process with cron, but how would I go about stopping it? I thought about starting a new process1 everyday at 00:00, then at 23:59 I'd start a process2 doing ps -aux | grep process1, getting the pid from the line and then killing it, but I was wondering if there's be a better way to do it.
I could use Python or Java too if it's easier with either language.

Record its PID:
nohup my_service &
echo $! > /var/run/my_service.pid
and then kill by that PID.
You might want to check both PID and process name to make sure that during the day the process did not crash and some other process did not get that PID. (And even better idea would be to set up supervisor.) But if you are sure that there are no other process with that name you can simply use pkill or killall.

Related

suspend/resume a process started from ~/.bashrc

I want to start a long-running python process when I log-in to a server.
So I put something like this into ~/.bashrc
python long_running_process.py
This correctly starts the python process on login. The problem here is that I'm not able to suspend it later (with ctrl-z). I can only exit the process by presssing ctrl-c.
I'd like to be able to pause/suspend and resume the python process if possible. This is different from "backgrounding" the process which has been asked and answered here
EDIT: I found a hack that kindof works. I create a dummy shell-script called ~/run.sh and make it executable. Then I put
#!/bin/bash
set -m
python long_running_process.py
in ~/run.sh.
Lastly, I call ~/run.sh in ~/.bashrc instead of starting the python process directly. Giving set -m enables job-control in the script (which is disabled by default for shell-scripts it seems)
This is very hacky. If someone has a nicer/cleaner solution, I'd be very interested in hearing it
You can use POSIX signals, sent with the kill command. I'll run this little Python script that prints its process id and the time once per second, then pause it then resume it:
#!/usr/bin/env python3
import os
import time
while True:
print(f"Process id: {os.getpid()}, time: {int(time.time())}")
time.sleep(1)
It started with process id 63070, so I can pause it with:
kill -STOP 63070
and then resume it with:
kill -CONT 63070
You can stop the process with command kill -SIGSTOP pid where pid is the process id (you can find it with command ps -ef | grep process_name ) and then continue the process with signal SIGCONT.

How do I handle stopping my service?

I've turned a program I wrote into a service, and I have a bash script that runs to start up the actual program, since there are things that have to be started in a particular order. The contents of the startup script (called with start-stop-daemon from the init.d script look like :
./rfid_reader &
sleep 2
java ReaderClass &
This works fine, but how do I go about killing them when it comes time to stop the process?
I've seen pidfiles used, do I just get the PIDs of the two programs, write them to a file, and then kill them when it comes time to shut them down, or do I have to ps -ef | grep program to get their PIDs?
I don't think killall is a good idea to do this. You'd better to record the PID of the program started in background in some file(e.g. PID_FILE) and then kill $(<$PID_FILE) to stop it.
Please refer to this thread for how to get the PID the previous started background program.
Assuming you know the name of your program, you can kill them as below :
killall -KILL program_name

Stop WebSphere JVM within time limit?

I am wondering if we can stop a Single JVM within specific time limit. If it is not stopping within that time limit then kill the process from shell script.
If we are executing ./stopServer.sh JVM_Name - It will run till the jvm will not get stopped or till any error and exit.
What I am trying to do is :./stopServer.sh JVM_Name - If this do not stopped within 2 min(suppose), then kill the process (But How to figure out it is not stopped within 2 mins through shell script before the process go for killing). I can write the condition to kill . But not sure how to do checks if the JVM stopped within 2 mins or not so that we can go ahead to kill process.
Can anyone please suggest shell script code to identify if the jvm is stopped within specific time limit or not?
A JVM is a process and as such can be stopped with the kill command - kill $processid or more brutal kill -9 $processid
If you start the JVM from a script using something like java ... then I suggest putting a & at the end of that line and in the following line
processid=$!
which saves the id of the background process.
Then
sleep 120
will wait for 2 min.
Now you have two options - either just kill
kill $processid /dev/null 2>&1
or first check if the processid might (very unlikely) be reused by another process (or use some other way to check if your JVM has finished, maybe a file that indicates this from your java program) and then if it matches use the kill.
ps -ef|grep -w $processid |grep -w java > /dev/null
If it has returncode zero then continue with the kill
test $? -eq 0 && kill $processid
I usually would trust that the processid is either my JVM or not used at all

How to quickly kill java processes in bash?

On a linux box, I have at most 3 java jars files running. How do I quickly kill all 3 with one command?
Usually I would:
ps ex - get the processes running
then find the process ids then do:
kill -9 #### #### ####
Any way to shorten this process? My eyes hurts from squinting to find the process ids.
My script does the following:
nohup ./start-gossip &
nohup ./start &
nohup ./start-admin &
Is there a way to get the process ids of each without looking it up?
Short answer:
pkill java
This looks up a process (or processes) to kill by name. This will find any other java processes too, so be careful. It also accepts -9, but you should avoid using -9 unless something is really broken.
EDIT:
Based on updates, you may be able to specify the script names to pkill as well (I'm not positive). But, the more traditional way to handle this issue is to leave pid files around. After you start a new process and background it, its pid is available in $!. If you write that pid to a file, then it's easy to check if the process is still running and kill just the processes you mean to. There is some chance that the pid will be reused, however.
You can save the PIDs when you start the processes so you can use them later:
nohup ./start-gossip &
START_GOSSIP_PID=$!
nohup ./start &
START_PID=$!
nohup ./start-admin &
START_ADMIN_PID=$!
...
kill -9 $START_GOSSIP_PID
kill -9 $START_PID
kill -9 $START_ADMIN_PID
This has the advantage (over pkill) of not killing off any other processes that coincidentally have similar names. If you don't want to perform the kill operation from the script itself, but just want to have the PIDs handy, write them to a file (from the script):
echo $START_GOSSIP_PID > /some/path/start_gossip.pid
Or even just do this when you launch the process, rather than saving the PID to a variable:
nohup ./start-gossip &
echo $! > /some/path/start_gossip.pid
To get the process id of that java process run
netstat -tuplen
Process ID (PID) of that process whom you want to kill and run
kill -9 PID

is there any way to know the pid of a launched program?

if I launch a bash script as a child, I can pass its own pid to the parent by using $$.
Is there any way to find the pid of a program that I launch from a script in background
like:
ping x.x.x.x &
what's the pid of that ping ?
(I just hope I expressed my self correctly ... my English is not the best)
PS. I'm looking for a simple and clean solution, I can imagine something like:
ping -t10000 -W10 x.x.x.x &
then
ps ax | grep 'ping -t10000 -W10 x.x.x.x'$
but is too complicated, also even that I used switches to personalize it is not clean, it may catch another processes in the system
The variable $! has the PID of the last background process you started.
Use this: $! right after executing the command whose PID you want. It means, though that you need to use an ampersand (&) after the command, to start it in background. E.g.:
my_command & CMDPID=$!
echo "$CMDPID"

Resources