Cher
Cher

Reputation: 2937

how to correctly write command inside commands (ssh)?

Here is the command I have which works

It's just a kill with an expression which returns a number

kill $(ps -ef | grep '[m]atchbox-panel --titlebar --start-applets showdesktop,windowselector' | cut -f8 -d' ') &> /dev/null

Here is the ssh I normally use

bash -c 'timeout  120s ssh -o StrictHostKeyChecking=no [email protected] "cd NightTest"'

I try to combine both of them

bash -c 'timeout  120s ssh -o StrictHostKeyChecking=no [email protected] "kill $(ps -ef | grep '[m]atchbox-panel --titlebar --start-applets showdesktop,windowselector' | cut -f8 -d' ') &> /dev/null"'

It doesn't work, my guess is that it gets mixed up with the ''.

Tried options

Escaping most of the ' in the kill commands :

 bash -c 'timeout  120s ssh -o StrictHostKeyChecking=no [email protected] "kill $(ps -ef | grep \'[m]atchbox-panel --titlebar --start-applets showdesktop,windowselector\' | cut -f8 -d\' ') &> /dev/null"'

Do not work either, I did many other tries but can't make it work.

Any ideas?

Added note

My system doesn't support pkill command

Upvotes: 0

Views: 121

Answers (2)

Jonathan Leffler
Jonathan Leffler

Reputation: 753675

Drop the bash -c notation. Assuming you don't rewrite the command to use pkill, then you need something like:

timeout 120s ssh -o StrictHostKeyChecking=no [email protected] \
    'kill $(ps -ef | grep "[m]atchbox-panel --titlebar --start-applets showdesktop,windowselector" | cut -f8 -d" ") &> /dev/null'

Note that I used double quotes inside the command to be executed. Fortunately, there was nothing in the command where it would matter whether single quotes or double quotes were used.

The version with 'embedded single quotes' doesn't work because you can't embed single quotes in a single-quoted string. You can, if you must, write '…'\''…' to get a single quote in between two ellipsis. The first ' terminates the current single quoted string (even if the preceding character is a backslash; there are no escapes in a single quoted string); the \' generates a single quote; the third ' in the centre group resumes the single quoted string again.

Thus, in your attempt:

bash -c 'timeout  120s ssh -o StrictHostKeyChecking=no [email protected] "kill $(ps -ef | grep \'[m]atchbox-panel --titlebar --start-applets showdesktop,windowselector\' | cut -f8 -d\' ') &> /dev/null"'

the Bash command sees:

timeout  120s ssh -o StrictHostKeyChecking=no [email protected] "kill $(ps -ef | grep \[m]atchbox-panel --titlebar --start-applets showdesktop,windowselector\ | cut -f8 -d\ ) &> /dev/null"

which means grep gets multiple arguments where you wanted one, etc. It completely breaks up the meaning.

Nesting quoting conventions is hard — really hard.

Upvotes: 3

John Kugelman
John Kugelman

Reputation: 361595

It'd be easier if you use pkill to kill the desired process. It performs the searching and killing all in one go.

pkill -f 'matchbox-panel --titlebar --start-applets showdesktop,windowselector'

Then you can throw that into the SSH call:

bash -c 'timeout 120s ssh -o StrictHostKeyChecking=no [email protected] pkill -f "matchbox-panel --titlebar --start-applets showdesktop,windowselector"'

What's the purpose of the bash -c, by the way? If you can get rid of that, then it's even simpler.

timeout 120s ssh -o StrictHostKeyChecking=no [email protected] pkill -f 'matchbox-panel --titlebar --start-applets showdesktop,windowselector'

Upvotes: 3

Related Questions