I'm trying to store the PID of a background process I need to launch as a non-root user.
When I execute the script below, the PID file is created but stays empty.
USER=myuser
PROG=/path/to/service
PROG_ARGS=""
PIDFILE=/var/run/$NAME.pid
su $USER -c "python2.7 $PROG $PROG_ARGS &"
echo $! > $PIDFILE
I've tried to place the & outside the su command like so su $USER -c "python ..." &, and it nearly worked since I get a PID but it's always the one before my actual process (Eg: if my python PID is 3101, the saved PID will be 3100). I suspect this is the PID of the shell that launched the python script.
My question is, how can I launch my python script as a specific user and save the PID at the same time?
I'm running RHLE 6.
The background process is created in the subshell started by su, so you need to capture $! there.
su $USER -c "python2.7 $PROG $PROG_ARGS & echo \$! > $PID_FILE"
Related
I am using ttyecho (can be installed with yay -S ttyecho-git) to execute a command in a separate terminal like so:
urxvt &
sudo ttyecho -n /proc/<pid-of-new-urxvt>/fd/0 <command>
It does not work because the /proc/pid-of-new-urxvt/fd/0 is a symlink that points to the /dev/pts/x of the parent terminal.
In the spawned urxvt I happen to run zsh. So if I use the pid of that zsh process it works:
sudo ttyecho -n /proc/<pid-of-new-zsh-within-new-urxvt>/fd/0 <command>
How can I get the pid of the new zsh process spawned within the new urxvt process when I run urxvt & ? Or is there a different solution to achieve the same result?
pgrep -P <pid-of-new-urxvt> gives the pid of the child zsh process.
Thx to #user1934428 for the brainstorming
Here is the resulting bash script:
urxvt &
term_pid=$!
# sleep here makes us wait until the child shell in the terminal is started
sleep 0.1
# we retrieve the pid of the shell launched in the new terminal
shell_pid=$(pgrep -P $term_pid)
# ttyecho executes the command in the shell of the new terminal and gives back control of the terminal so you can run further commands manually
sudo ttyecho -n /proc/${shell_pid}/fd/0 "$#"
So when I launch "script ls" it opens a new terminal, runs ls, and gives back the prompt with the terminal still open.
I just had to add ttyecho in the sudoers file.
I set up a cron job on a linux server to kill and restart a python script (run.py) every other day. I set the job to run as root, but I find that sometimes it doesn't kill the process properly (and ends up running two scripts in a row).
Is there a better way to do this?
My cron job parameters:
0 8 * * 1,4,7 cd /home/myUser && ./start.sh
start.sh:
#!/bin/bash
echo "Running..."
sudo pkill -f run.py
sudo python run.py &
I guess run.py runs as python, not run.py. So you won't find anything with kill -f run.py.
You should echo the PID of the process to a file and use that value to kill the previous process if it's still running. Just add echo $! >/path/to/pid.file as the last line in your start.sh script to do so.
Read more:
https://serverfault.com/questions/205498/how-to-get-pid-of-just-started-process
How to read a file into a variable in shell?
http://www.cyberciti.biz/faq/kill-process-in-linux-or-terminate-a-process-in-unix-or-linux-systems/
Example to get you started:
#!/bin/bash
echo "Running..."
sudo pkill -F /path/to/pid.pid
sudo python /path/to/run.py &
echo $! > /path/to/pid.pid
Another alternative to this is making the python script run on upstart if you are on a system that supports upstart. Then you can just do sudo /sbin/start job_name at the begin and sudo /sbin/stop job_name this makes upstart manage the pids for you.
Python upstart script
Upstart python script
I'm trying to capture the PID of a program that I am running for my init script so I can come back and kill it later. When I run the script without being a different user, the command works just fine, and I get the PID in a variable. I can execute the same command as a different user, however, I cannot get the PID for that command to store in a variable. This is what I get.
[root#fenix-centos ~]# PID=`su - $USER -c "$DAEMONPATH $DAEMONPATHARGS $DAEMON $DAEMONARGS > /dev/null 2>&1 & echo \$! "`
[root#fenix-centos ~]# echo $PID
...and nothing. Is there some weird thing that would prevent me from getting the PID of a process being started by a different user and storing that PID in a variable? The process still starts, but I'm not getting the PID.
After going though the link to your script, i suggest this approach:
Perform variable (that you're passing as argument to your command su) assignment in a file:
[tom#jenkins ]# cat source_file
DAEMONPATH=/usr/bin/java
DAEMONPATHARGS='-jar -Xmx768'
DAEMON=/opt/megamek-0.38.0/MegaMek.jar
DAEMONARGS='-dedicated -port 2346'
Source the above file in your command:
PID=`su - $USER -c '. source_file; $DAEMONPATH $DAEMONPATHARGS $DAEMON $DAEMONARGS > /dev/null 2>&1 & echo $! '`
It seems your syntax is not working because the $! must be getting evaluated by the original shell which is running su and not the shell that su runs.
in a shell script i have a command like, pid -p PID, after that i have some more commands. but as soon as the pid -p PID command runs we should supply a control+C to exit from it and then only the further commands executes. so i wanna do this periodically, i have all the things i want in a shell script and i wanna put this into crontab. the only thing that bothers is, if i schedule this script in the crontab, afetr its first execution, the command pid -p PID, how will i supply the CONTRO+C command for allowing further commands to execute???? please help
my script is like this.. very simple one
top -p $1
free -m
netstat -antp|grep 3306|grep $1
jmap -dump:file=my_stack$RANDOM.bin $1
You can send signals with kill. In your case however, you can just restrict top to one or a few iterations
top -p $1 -n 1
Update:
You can redirect the output of a command to a file. Either overwrite the file each time
command.sh >file.txt 2>&1
or append to a file
command.sh >>file.txt 2>&1
If you don't want the error output, leave out the 2>&1 part.
pid -p PID &
some_pid=$!
kill -s INT $some_pid
a strange thing to me
a script while.sh,it's content is:
while [ 1 ];do
sleep 1
echo `date`
done
run as $while.sh >& while.log & (without nohup or disown or setsid or double fork())
exit and login again can see this process is still exist,it's ppid is 1 and it's tty is ?
my system is rhel6(rhel5 is the same, bash
in centos5.x it must use nohup or disown or do double fork() in code
what happen in rhel6
Is the huponexit shell option set?
$ shopt
...
huponexit off
Bash will send a SIGHUP signal to its jobs if it receives a SIGHUP itself, but it won't signal them when it exits normally unless you enable this option.
For what it's worth this is disabled on both RHEL6 and RHEL5, at least on the systems I just tested. I tried this command:
$ sleep 1000 &
It was not killed when I logged out and logged back in unless I deliberately enabled shopt -s huponexit.