My Shell, My Bell: While/Xargs by Example

Earlier today I logged into a jumpbox session and was greeted with some lovely error messages:

$ channel 12: open failed: administratively prohibited: open failed
channel 13: open failed: administratively prohibited: open failed
channel 19: open failed: administratively prohibited: open failed
channel 20: open failed: administratively prohibited: open failed
channel 21: open failed: administratively prohibited: open failed
channel 22: open failed: administratively prohibited: open failed
channel 23: open failed: administratively prohibited: open failed
channel 24: open failed: administratively prohibited: open failed
channel 25: open failed: administratively prohibited: open failed

Was a little odd, considering that I hadn’t done anything yet. So I looked through a list of my running processes and noticed that I had a ton of ssh-agent and ssh -R sessions still running. That’s what I get for scripting and not cleaning up, but that’s an issue for another day.

My main issue was figuring out how to get all those PIDs and delete them in a loop, because why would I go through probably a hundred processes one by one? (I may be exaggerating a little… but not by much.)

To create the PID lists, I used:

ps -o pid,cmd -u quinn | grep "ssh-agen[t]  " | awk '{print $1}'
ps -o pid,cmd -u quinn | grep "ssh -R 2022" | awk '{print $1}'

(I actually have ps -o pid,cmd -u ${USERNAME} aliased to myps to make my life even easier.) To delete I could use either a WHILE loop or XARGS. Since the list of processes was relatively small, either would work in this case. For WHILE:

ps -eo pid,cmd -u quinn | grep "ssh-agen[t]  " | awk '{print $1}' | while read PID; do kill ${PID}; done

And for XARGS:

ps -o pid,cmd -u quinn | grep "ssh -R 2022" | awk '{print $1}' | xargs -n1 kill -TERM

A Quick XARGS Note

A quick overview of the syntax for the xargs command as I used its: the -n1 tells xargs to "group" the arguments individually, so it’s actually running kill -TERM ${PID} for each PID. For situations like rm where you could want multiple arguments at once, e.g. find /home -name '*.bak' | xargs rm to recursively remove all the *.bak files out of /home, then larger groups could be used. When a grouping size isn’t specified, like in the rm example, then xargs will simply use the largest group size that particular command can handle.

Spread the word

twitter icon facebook icon linkedin icon