0

HI I`m trying to execute something like this:

ssh USER@SERVER 'command=`ps -aux | grep xyz | grep -v grep | awk '{ print $11}'` && echo $command'

and I get

awk: cmd. line:1: {
awk: cmd. line:1:  ^ unexpected newline or end of string

Is there any way to get it working?

Please, help me! Thanks a lot!

1
  • 3
    grep xyz | grep -v grep | awk '{...}' is more simply expressed as awk '/[x]yz/{...}' Commented Dec 16, 2017 at 22:34

2 Answers 2

3

Simpler command

Try:

ssh USER@SERVER 'ps -p "$(pgrep -d, xyz)" -o comm='

Notes

  1. -p "$(pgrep -d, xyz)" selects for commands whose names include the string xyz.

  2. -o comm= selects the output format that you want.

Quoting and the original command

Instead of the original command, try:

ssh USER@SERVER 'command=`ps -aux | grep xpdf | grep -v grep | awk '\''{ print $11}'\''` && echo $command'

Observe, that inside quoted command string, ' has been replaced with '\''.

Discussion

This is not one single-quoted string:

'command=`ps -aux | grep xyz | grep -v grep | awk '{ print $11}'` && echo $command'

It consists of the following:

  1. A single quoted string:

    'command=`ps -aux | grep xyz | grep -v grep | awk '
    
  2. An unquoted string:

    { print $11}
    
  3. A single-quoted string:

    '` && echo $command'
    

There is no way to put single-quotes inside single quoted strings. One has to end the first single-quoted string with a closing single-quote, follow it with an escaped single-quote, and follow this with a single-quote to open a single-quoted string.

Sign up to request clarification or add additional context in comments.

Comments

0

There's a bunch that's confusing here. First: you can restructure your remote command entirely within awk:

awk 'BEGIN { cmd="ps aux"; while( (cmd | getline) >0) {if($0 ~ /xyz/) print $11}}'

If you happen to know which field you expect "xyz" to occur in, you can test that directly and eliminate your negative test (which I've omitted above). We can add that back if you insist:

awk 'BEGIN { cmd="ps xyz"; while( (cmd | getline) >0) {if($0 ~ /xyz/ && $0 !~ /awk/) print $11}}'

But say I'm interested in what user clamav is up to:

awk 'BEGIN { cmd="ps aux"; while( (cmd | getline) >0) {if($1 ~ /clamav/) print $11}}'

Another issue is that you're defining and echoing an environment variable remotely, which introduces a bunch of complications. Why not exploit SendEnv instead. Generally this is LANG LC_*, but the latter is liberal as to what it allows:

export LC_command="awk 'BEGIN { cmd=\"ps aux\"; while( (cmd | getline) >0) {if($1 ~ /clamav/) print $11}}'"
ssh -o USER@HOST 'echo $LC_command'

Other options include providing a script or shell function which can be executed remotely, which avoids a lot of SSH & shell quote fumbling.

Any more clarification on what you're hoping to accomplish?

7 Comments

That will spin off into an infinite loop if the getline fails.
Can you provide an example? If getline has no output, the while loop terminates. The awk script terminates on no output. If ps produces an infinite list of processes, I'd suggest you've other problems.
Any kind of shell problem in the call to cmd. Given a failure, getline returns -1 which is non-zero and so while (cmd|getline) will continue looping and, presumably, failing. The correct syntax for calling getline is while ( (cmd|getline) > 0 ).
How might getline return a -1? I've checked against, say, 'cmd="false"' and 'cmd="notacommand"', and both terminate: awk 'BEGIN { cmd="notacommand"; while( cmd | getline) print i++; }'
Thanks again. Agreed absolutely on defensive programming. I try to practice that, so long as I'm aware of what to defend against.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.