This question already has an answer here:
-
How do I set a variable to the output of a command in Bash?
14 answers
I'm trying to write a simple script for killing a process. I've already read Find and kill a process in one line using bash and regex so please don't redirect me to that.
This is my code:
LINE=$(ps aux | grep '$1')
PROCESS=$LINE | awk '{print $2}'
echo $PROCESS
kill -9 $PROCESS
I want to be able to run something like
sh kill_proc.sh node
and have it run
kill -9 node
But instead what I get is
kill_process.sh: line 2: User: command not found
I found out that when I log $PROCESS
it is empty.
Does anyone know what I'm doing wrong?
PROCESS=$(echo "$LINE" | awk '{print $2}')
or
PROCESS=$(ps aux | grep "$1" | awk '{print $2}')
I don't know why you're getting the error you quoted. I can't reproduce it. When you say this:
PROCESS=$LINE | awk '{print $2}'
the shell expands it to something like this:
PROCESS='mayoff 10732 ...' | awk '{print $2}'
(I've shortened the value of $LINE
to make the example readable.)
The first subcommand of the pipeline sets variable PROCESS
; this variable-setting command has no output so awk
reads EOF immediately and prints nothing. And since each subcommand of the pipeline runs in a subshell, the setting of PROCESS
takes place only in a subshell, not in the parent shell running the script, so PROCESS
is still not set for later commands in your script.
(Note that some versions of bash
can run the last subcommand of the pipeline in the current shell instead of in a subshell, but that doesn't affect this example.)
Instead of setting PROCESS
in a subshell and feeding nothing to awk
on standard input, you want to feed the value of LINE
to awk
and store the result in PROCESS
in the current shell. So you need to run a command that writes the value of LINE
to its standard output, and connects that standard output to the standard input of awk
. The echo
command can do this (or the printf
command, as chepner pointed out in his answer).
You need to use echo
(or printf
) to actually put the value of $LINE
onto the standard input of the awk
command.
LINE=$(ps aux | grep "$1")
PROCESS=$(echo "$LINE" | awk '{print $2}')
echo $PROCESS
kill -9 $PROCESS
There's no need use LINE
; you can set PROCESS
with a single line
PROCESS=$(ps aux | grep "$1" | awk '{print $2}')
or better, skip the grep
:
PROCESS=$(ps aux | awk -v pname="$1" '$1 ~ pname {print $2}')
Finally, don't use kill -9
; that's a last resort for debugging faulty programs. For any program that you didn't write yourself, kill "$PROCESS"
should be sufficient.