Kill a process in ruby - ruby

I use this code to kill a process with a PID file:
Process.kill 15, File.read('/tmp/pidfile').to_i
But the following two examples never work, when i try:
system "kill `cat /tmp/file.pid`"
or
`kill \`cat /tmp/pidfile\``
output is:
sh: 1: kill: Usage: kill [-s sigspec | -signum | -sigspec] [pid | job]... or
kill -l [exitstatus]
Is there a problem with the backstick ? because in bash this works perfectly:
kill `cat /tmp/file.pid`

The string is not being interpolated. This does not run a cat command:
system "kill `cat /tmp/file.pid`"
Instead, you could write this as:
system "kill #{`cat /tmp/file.pid`}"
However, I'm unclear why you'd choose to do this over your original (working) method.

Related

Kill usage alert keeps popping up

I keep getting the following message whenever I run my bash script:
kill: usage kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
This is the line it happens on, when I am trying to kill all instances of methserver:
kill $(ps aux | grep '[m]ethserver' | awk '{print $2}')
How do I fix it? Would like to get rid of this annoying message!
Obviously you're giving it bad input or it wouldn't be outputting a usage message. In any case, there is a tool to do this for you.
pkill methserver

Cannot kill a windows process in cygwin

I can kill a windows process in Cygwin with the command:
$ echo "4128" | xargs kill -f
but cannot do it with the following command:
$ kill -f 4128
-bash: kill: f: invalid signal specification
According to documentation of kill the syntax should be correct https://cygwin.com/cygwin-ug-net/kill.html
You can find there:
$ kill -f 123
Why doesn't the second command work?
Cygwin has 2 kills:
$ type -a kill
kill is a shell builtin
kill is /usr/bin/kill
The shell builtin does not support the -f option. You need to use the kill
executable:
/bin/kill -f
Or:
env kill -f

How to suppress command output from makefile?

My make file looks like:
nstop:
#kill `cat ${APP_ROOT}/run/nginx.pid` ||:
But I still get output:
$ make nstop
cat: /run/nginx.pid: No such file or directory
/bin/sh: 1: kill: Usage: kill [-s sigspec | -signum | -sigspec] [pid | job]... or
kill -l [exitstatus]
How to suppress output from command at backtick?
I have resolved that by redirecting error output into /dev/null:
nstop:
#kill `cat ${APP_ROOT}/run/nginx.pid 2>/dev/null` 2>/dev/null ||:
But, I think, there should be better solution.

kill command doesn't work with redirection

ok so i am trying to execute kill command using
kill < ff // Doesn't work
cat ff | kill //Doesn't work
where the ff is text file containing a list of pid's.
7688 7697 7705 7760 7764 7772 7785 7810 7817 7865 7874 8036 8097
Output of kill is as follows for both the above commands is :
kill: usage:kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
Did you try this?
kill $(cat ff)
?
The shell builtin kill or the external one /bin/kill does not take Process ID (or Job ID) via standard input stream. You need to pass them as argument to kill, so:
kill -- $(<ff)
should do.
If you want to kill them one by one and doing something in between, you can create an array with the pids and iterate over them:
pids=( $(<file.txt) ) && for i in "${pids[#]}"; do echo "killing $i"; kill -- "$i"; done
This one too:
$ cat ff|xargs kill
An option using egrep (or grep -E) that accounts for some whitespace anomalies
egrep -o "[0-9]+" ff | kill "$(cat -)"
Which will work for a file that looks like this;
ff:
7688 7697 7705 7760 7764 7772
7785 7810 7817
7865
7874
8036 8097
Thanks for the replies. Both of these works.
kill $(cat ff)
kill -- $(<ff)
It means that kill doesn't take inputs from standard inputs.

How to get pid of piped command?

(or How to kill the child process)?
inotifywait -mqr --format '%w %f %e' $feedDir | while read dir file event
do
#something
done &
echo $! #5431
ps eg:
>$ ps
PID TTY TIME CMD
2867 pts/3 00:00:02 bash
5430 pts/3 00:00:00 inotifywait
5431 pts/3 00:00:00 bash
5454 pts/3 00:00:00 ps
It seems if I kill 5431 then 5430 (inotifywait) will be left running, but if I kill 5430 then both processes die. I don't suppose I can reliably assume that the pid of inotifywait will always be 1 less than $!?
When we run a pipe, each command is executed in a separated process. The interpreter waits for the last one but if we use ampersand (&).
cmd1 | cmd2 &
The pid of processes will be probably close, but we cannot assume it reliably. In the case where the last command is a bash reserved word as while, it creates a dedicated bash (that's why your 'dir', 'file' variables won't exist after the done keyword). Example:
ps # shows one bash process
echo "azerty" | while read line; do ps; done # shows one more bash
When the first command exits, the second one will terminate because the read on the pipe return EOF.
When the second command exits, the first command will be terminated by the signal SIGPIPE (write on a pipe with no reader) when it tries to write to the pipe. But if the command waits indefinitely... it is not terminated.
echo "$!" prints the pid of the last command executed in background. In your case, the bash process that is executing the while loop.
You can find the pid of "inotifywait" with the following syntax. But it's uggly:
(inotifywait ... & echo "$!">inotifywait.pid) | \
while read dir file event
do
#something
done &
cat inotifywait.pid # prints pid of inotifywait
If you don't want the pid, but just be sure the process will be terminated, you can use the -t option of inotifywait:
(while true; do inotifywait -t 10 ...; done)| \
while read dir file event
do
#something
done &
kill "$!" # kill the while loop
None of this solution are nice. What is your real achievement? Maybe we can find a more elegant solution.
If your goal is to make sure all of the children can be killed or interrupted elegantly. If you're using BusyBox's Ash, you don't have process substitution. If you don't want to use an fd either, check out this solution.
#!/bin/sh
pid=$$
terminate() {
pkill -9 -P "$pid"
}
trap terminate SIGHUP SIGINT SIGQUIT SIGTERM
# do your stuff here, note: should be run in the background {{{
inotifywait -mqr --format '%w %f %e' $feedDir | while read dir file event
do
#something
done &
# }}}
# Either pkill -9 -P "$pid" here
wait
# or pkill -9 -P "$pid" here
Or in another shell:
kill <pid ($$)>

Resources