how to correctly write command inside commands (ss

2019-09-18 04:30发布

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 root@192.168.155.XXX "cd NightTest"'

I try to combine both of them

bash -c 'timeout  120s ssh -o StrictHostKeyChecking=no root@192.168.155.148 "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 root@192.168.155.148 "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

标签: bash ssh
2条回答
我命由我不由天
2楼-- · 2019-09-18 04:47

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 root@192.168.155.148 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 root@192.168.155.148 pkill -f 'matchbox-panel --titlebar --start-applets showdesktop,windowselector'
查看更多
\"骚年 ilove
3楼-- · 2019-09-18 04:54

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 root@192.168.155.148 \
    '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 root@192.168.155.148 "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 root@192.168.155.148 "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.

查看更多
登录 后发表回答