We help IT Professionals succeed at work.

want to redirect the output of kill command in a file

piari
piari asked
on
i am writing script(ksh) in which i want to check return status(success/ failure) of kill command. when i try to redirect it into file through scripting it doesn't work but if i try it on terminal it works.

kill -9 Processid > Temp

isn't it strange

when i tried to redirct standard error it works but still give standard output (success message) on terminal

kill -9 Processid 2> Temp
i also try to redirect both error and standard output in to same file but it also not works :-(

kill -9 Processid > Temp 2>&1


Comment
Watch Question

Commented:
The easiest solution for shell scripting is checking the result code:

#!/bin/ksh

kill -9 99999
if [ $? -gt 0 ]; then
   echo ERROR
fi

Does this help ?

Author

Commented:

Author

Commented:
Hi kyrmit
kill command still gives message on terminal
in case of failure give message
kill: no such process
and in case of success give message
[1]  + Killed               man ps

i want to redirect these messages into file
i don't want these messages on terminal when my script run.

Commented:
My appologise, I misunderstood.

The message is send from the shell. In order to prevent those, use a subshell command around the command:

For bash : ( kill -1 <pids> ) >/dev/null

For Bourne shell also possible : sh -c "kill -1 <pids>" >/dev/null

Does this help ?

K.


CERTIFIED EXPERT

Commented:
kill -9 pid 2>&1 >/tmp/tmp
CERTIFIED EXPERT

Commented:
if you want to keep all the infor in a log file, you should use:

   kill -9 pid >>/mylogdir/logs 2>&1

Author

Commented:
hi kyrmit
it not works :-(
i tried it like that
(kill -1 123 ) >/dev/null

i also tried
kill -9 pid 2>&1 >/tmp/tmp
kill -9 pid >>/mylogdir/logs 2>&1
but it also not works

CERTIFIED EXPERT

Commented:
could you please post the message you get for each examlpe you testes.
Which shell are you using?
what does    which kill     tell you?

Author

Commented:

#!/bin/ksh
kill -9 3985 2>&1 >Temp
#got the folowing message on the terminal
#kill: 3985: no such process

kill -9 4425 >> Temp 2>&1
#this redirect errors into Temp files but got the success messages on terminal
#[2]  - Killed               man ps

( kill -1 111 )  >/dev/null
#this do nothing and got both error and success messages on termianl
#kill: 111: no such process

Commented:
>kill -9 3985 2>&1 >Temp
>#got the folowing message on the terminal
>#kill: 3985: no such process

You have to do a >Temp first before the redirection of 2 can take place. if kill says "no such process", I guess there wasn't a process with this PID.

>kill -9 4425 >> Temp 2>&1
>#this redirect errors into Temp files but got the success messages on terminal
>#[2]  - Killed               man ps

You found the right process, but the message comes from the shell where "man ps" was invoked. This shell tells you that a process got killed. If you don't want to see it you have to start it in its own shell ... like "(man ps&) 2>>/dev/null".

Suggestions:
1) start the process you want to kill in its own shell, so you will be able to capture this shell's output.
2) "kill -9 <PID> >> temp 2>&1" will capture kill's output.

======
Werner

Commented:
To clarify, there are two different things in operation: one is the error message of 'kill', which cannot find the process which goes to stderr - thus 'kill -9 5555' 2>/dev/null will deal with this.

The other message is from the shell, which notifies you that a background process died. The shell is the one you issue the command from. Thus you still see the "[2] killed" message. Contrary to my initial message, there is nothing you can do to prevent this after the event. Bash will always report if it's children have received a kill signal.

The only 'radical' treatment I can come up with on short notice is the
following :

exec 4>/tmp/out
exec 2>&4
any command (with most output of it invisible)
exec 2>&1

Now every error message from "any command" ends up in the file /tmp/out. This can be rather awkward. However you should be safe if you are doing this within a script.

BTW: it's fun to watch the out file "tail -f /tmp/out" and see your keyboard input appearing in another window ;-)

Author

Commented:
hi kyrmit


#!/bin/ksh
exec 4>/tmp/out
exec 2>&4
exec 2>&1
process=12091
kill -9 "$process"

*******************************************************

it's not working and i am getting success and failure both messages on terminal when i run this script

Author

Commented:
hi kyrmit


#!/bin/ksh
exec 4>/tmp/out
exec 2>&4
exec 2>&1
process=12091
kill -9 "$process"

*******************************************************

it's not working and i am getting success and failure both messages on terminal when i run this script
CERTIFIED EXPERT

Commented:
> >#[2]  - Killed               man ps
> You found the right process, but the message comes from the shell where "man ps" was invoked.

see man ksh, he set -b and set -m options to avoid this
**and again my questions**

Which (interactive) shell are you using?
what does    which kill     tell you?

Commented:
piari,
  you mixed up the order of the commands. The last statement below is resetting the output to (almost) normal. So do this 'after' you run the kill command.

exec 4>/tmp/out
exec 2>&4
process=12091
kill -9 "$process"
exec 2>&1

Author

Commented:
ahoffmann
i am using korn shell and already told in my comments about what each kill say
my research told me that it  is impossible to catch whose success messages because when we kil any process the shell which have spawn that process must confirm the termiantion of that process on terminal. it always happen in case we use -9 option

Commented:
piari,
  I take it you didn't succeed yet. I give it one more shot... (hope you do too). The reason why the message still comes through is that the bash only displays it after finishing some processing. Hence the redirection in my example won't work. Sorry about this, I should have remembered this.

Now I tried the following  :

#now the '_wrong_' way
[rh@localhost rh]$
[rh@localhost rh]$ man perl &
[2] 31102
[rh@localhost rh]$
[2]+  Stopped (tty output)    man perl
[rh@localhost rh]$ export notify=1 ; exec 4>/tmp/out ; exec 2>&4 ; kill -9 31102 ;  exec 2>&1
[rh@localhost rh]$
[2]+  Killed                  man perl

#now the _right_ way
[rh@localhost rh]$ man perl &                                                   
[2] 31112
[rh@localhost rh]$
[2]+  Stopped (tty output)    man perl
[rh@localhost rh]$ export notify=1 ; exec 4>/tmp/out ; exec 2>&4 ; kill -9 31112 ; sleep 1 ; exec 2>&1
[rh@localhost rh]$

There is nooutput for the last line. The reason is that during the one second 'sleep', the message gets redirected into /tmp/out instead of the screen. Indeed, tmp out contains now :

[rh@localhost rh]$ cat /tmp/out
[2]+  Killed                  man perl

I am using bash in this example.

If you have a really slow system, you may have to sleep for 2 seconds. Mine was a 500MHz Pentium III.

Author

Commented:
kyrmit
it not works :-(. i am still getting success message on terminal when the script completes.
i already told you if you try to redirect it from command prompt it works the problems araise when you write it in script and then run that script

will you please expalin this line in detail as i have no idea of exec command nor i know what 4 stands for.


 export notify=1 ; exec 4>/tmp/out ; exec 2>&4 ; kill -9 31112 ; sleep 1 ; exec 2>&1


Commented:
Piari,
  "notify=1" only works in BASH. Try the following command for KSH:  

$ set -b notify ; exec 4>/tmp/out ; exec 2>&4 ; kill -9 4068 ; sleep 1 ; exec 2>&1

The reason for this is the notify bit. You have to instruct the shell to tell you about the dead process right away (notify on), rather than before the next command. Unless you do this, and by default, the notification will be queued until you execute the next command.

Here is how it works:
  There are 3 standard file handles available in a shell, stdin (0), stdout (1) and stderr (2). Errors (and these annoying success messages) go to stderr. Normal output goes to stdout. Additionally, each shell has up to 6 more file handles reserved in case one needs to use them, nos. 3 to 9.

You can direct any of these file handles and any other, e.g. stdout into a file : 1>/tmp/this_is_stdout, stderr into a file 2>/tmp/this_is_stderr or both into the same file 2>&1 1>/tmp/this_is_both_stderr_and_stdout. I guess you knew this bit.

Now you can also direct those filehandles to each other, like here .. 2>&4 directs stderr to file handle for which is directed to /tmp/out.

So, if you were to do a "kill -9  1111 2>/tmp/out", the error message of kill will end up in /tmp/out. Why ? Because in order to execute this command your shell calls a vfork() or exec() system call. Thus kill runs in a _copy_ of your shell. And this copy has it's own 9 handles (although copied from the parent) and only the copy's stderr output redirected, not the one of your shell.

We already established that the annoying success message comes from your shell once the command finished to tell you all about it. So how do we redirect the output of the _current_ shell ? Either you have to redirect it before the shell starts, i.e. using a "subshell" to start and run and finish kill. Or you have to instruct your _current_ shell not to use vfork() or exec(), but to act on the current file handles. And this is what exec does.

Rather than tweaking the file handles of the _copy_ it does it on the current shell. So if you do exec 2>&1 1>/dev/null, you will never see any output of your current shell again.

To answer your question, the 4 is one of the provided file handles which I abused in order to log the output of stderr. It is not necessary for this command, you could leave it out and run exec 2>/dev/null instead of exec 2>&4.
 

Hope this clears it up
CERTIFIED EXPERT

Commented:
things get wired, at least for the questioner
So I recommend to make some simple checks and test so that you get used to the shells notify concept (as described several times in previous comments). Also use kill in all examples with full path (just in case of ..)

Please check your required commands
   1. from interactive shell (ksh)
   2. write a ksh script using exactly the same literals you printed in the interactive shell
   3. compare the results you get in your /tmp/out file for both actions above (and I'm pretty shure that they are identical)
   4. if the result is not identical and/or not what you expect, post what you have done, complete commands and scripts please
CERTIFIED EXPERT

Commented:
No comment has been added lately, so it's time to clean up this Topic Area.
I will leave a recommendation for this question in the Cleanup topic area as follows:

- PAQ, no points refunded

Please leave any comments here within the next 7 days

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER !

tfewster
Cleanup Volunteer
Commented:
Finalized as proposed

modulo

Community Support Moderator
Experts Exchange