Script shell get id and kill process

0

Please, i can't find the error in my command.

ssh -t root@$machine -x "sshpass -p 'ubuntu' ssh -t root@$address -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/nul -x 'ps -ef | grep "myprocess" | awk {print $2} | xargs kill'"

I have this error:

awk: line 2: missing } near end of file

Have you an idea ?

researcher

Posted 2015-05-29T11:41:30.303

Reputation: 324

awk format is different. Instead of awk {print $2} use awk '{print $2}'. You need to refactor your code – Romeo Ninov – 2015-05-29T11:44:11.130

@RomeoNinov That won't work directly, because OP is already using '' to quote the ps -ef and pipes command. – a CVn – 2015-05-29T11:44:48.287

@MichaelKjörling,yes, but awk will not work (in above example) also. So as I mention he/she should rewrite the code :) – Romeo Ninov – 2015-05-29T11:46:15.497

@RomeoNinov: same error "awk: line 2: missing } near end of file" – researcher – 2015-05-29T11:48:08.460

@researcher check above comments and replace awk with cut for example: http://unix.stackexchange.com/questions/65932/how-to-get-the-first-word-of-a-string

– Romeo Ninov – 2015-05-29T11:54:00.603

What about using pkill? – Michael Vehrs – 2017-01-23T14:11:38.023

Answers

1

For this type of problems, it's usually best to start by breaking it into its constituent parts. Start with the innermost expression, which seems to aim to get all PIDs for myprocess in order to signal them, and work your way outwards, testing each step along the way to make sure it gives the output you expect.

You are doing this by taking the output of ps, grepping for the process, running the output through awk to extract the relevant PID, then passing that to xargs. By looking at what you are actually trying to accomplish rather than the specific problem you're facing, I can tell that there are at least two much better ways to do this, which also coincidentally totally avoid the problem you are facing (which is based on having a number of layers of quoting within a single compound command).


One is to keep the ps and use its -C and -o parameters to get only the information you are interested in. This is actually mentioned as an example in the ps(1) man page. You would then want:

ps -C myprocess -o pid=

which will print only the PID(s) of any processes with the image name myprocess. This can then trivially be piped into xargs, replacing your ps ... | xargs kill with:

ps -C myprocess -o pid= | xargs kill

or possibly using process substitution to avoid the pipe and xargs entirely:

kill $( ps -C myprocess -o pid= )

The even better alternative is to use killall to signal all processes with a given image name directly:

killall -e myprocess

Here, -e specifies "exact" mode, in which process image names much match exactly. In this case, replace your ps ... | xargs kill entirely with the above.


-o UserKnownHostsFile=/dev/nul

Oh, and the conventional name is /dev/null, not /dev/nul. NUL is CP/M-ism from the mid-1970s, carried forward by Microsoft into current versions of Windows. In this particular case, the effect may or may not be the same, depending on how strict your ssh is.

a CVn

Posted 2015-05-29T11:41:30.303

Reputation: 26 553