tags:

views:

848

answers:

5

Let's suppose I have a bash script (foo.sh) that in a very simplified form, looks like the following:

echo "hello"
sleep 100 &
ps ax | grep sleep | grep -v grep | awk '{ print $1 } ' | xargs kill -9
echo "bye"

The third line imitates pkill, which I don't have by default on Mac OS X, but you can think of it as the same as pkill. However, when I run this script, I get the following output:

hello
foo: line 4: 54851 Killed                  sleep 100
bye

My question is thus: how I suppress the line in the middle so that all I see is hello and bye?

A: 
ps ax | grep sleep | awk '{ print $1 } ' | xargs kill -9 2> /dev/null

EDIT: This is an answer for when the question was revised.

I'd suggest not using xargs.

kill -9 $(ps ax | grep sleep | grep -v grep | awk '{ print $1 } ')
ashawley
I'd be surprised if that worked. Also, it hides real errors from the kill command.
Joshua
Yes, like Joshua said, that doesn't work for me. The messages still get through.
Chris Bunch
@Joshua: It works, the OP changed the question entirely.
ashawley
@Chris: Well, you've changed the target. I'd now like to suggest not using xargs. It avoids the output from Bash about successfully killing the process, and you don't lose job control. Though I doubt you'd need it in shell programming.
ashawley
@ashawley: My original comment was in response to your original suggestion not working, but I will keep in mind not using xargs and using your other suggestion. Thanks!
Chris Bunch
@Chris: I see, I guess there were originally 2 messages, one was standard the other was not. Avoiding xargs seems to be the better solution. ;)
ashawley
+2  A: 

The message is real. The code killed the grep process as well.

Run ps ax | grep sleep and you should see your grep process on the list.

What I usually do in this case is ps ax | grep sleep | grep -v grep

EDIT: This is an answer to older form of question where author omitted the exclusion of grep for the kill sequence. I hope I still get some rep for answering the first half.

Joshua
Yes, I'm aware of that, and that's fine with me. But what I'm looking for is a way to supress the messages on the second and third lines. Thanks though!
Chris Bunch
Yes, I had made the change to include your suggestion to omit grep from the list of things to kill, but that wasn't the point of the question. I was just looking for a way to suppress the output, not to omit "grep sleep" from the list.
Chris Bunch
+3  A: 

How about disown? This mostly works for me on Bash on Linux.

echo "hello"
sleep 100 &
disown
ps ax | grep sleep | grep -v grep | awk '{ print $1 } ' | xargs kill -9
echo "bye"

Edit: Matched the poster's code better.

jhs
Of course, if you do this then you lose job control, so you can't do kill %1 or whatever later. I'm not sure if you can get away with that but in most cases you probably can. These days if you're getting into fancy job control you'll be in Perl or whatever.
jhs
Great, that seems to do it! I'll look into the implications of losing job control with my app but it should be fine. Thanks!
Chris Bunch
A: 

Have you tried to deactivate job control? It's a non-interactive shell, so I would guess it's off by default, but it does not hurt to try... It's regulated by the -m (monitor) shell variable.

Varkhan
+5  A: 

While disown may have the side effect of silencing the message; this is how you start the process in a way that the message is truly silenced without having to give up job control of the process.

{ command & } 2>/dev/null

If you still want the command's own stderr (just silencing the shell's message on stderr) you'll need to send the process' stderr to the real stderr:

{ command 2>&3 & } 3>&2 2>/dev/null

To learn about how redirection works:

And by the way; don't use kill -9.

I also feel obligated to comment on your:

ps ax | grep sleep | grep -v grep | awk '{ print $1 } ' | xargs kill -9

This will scortch the eyes of any UNIX/Linux user with a clue. Moreover, every time you parse ps, a fairy dies. Do this:

kill $!

(There is a reason why pkill, pgrep isn't in OS X: It's a broken tool by design.)

lhunath
Great, thanks for the links! I'm checking them out now, but your first code snippet doesn't produce the intended output (at least not on OSX). The second one works as expected though.
Chris Bunch