0

Note - I posted a similar question yesterday and got a bit further thanks to @cas but am still having problems. I've refined the question so have re-asked it.

I'm passing script text to an ssh command (see below). Inside the script text there are variables that should be expanded. $1 and $2 and $logfilepattern seem to expand fine in the script string. However, $f does not. I've tried every combination of double quotes and single quotes and escapes I can think of but still can't get this to work. Any help appreciated.

Thanks, Max

#!/bin/bash
logfilepattern="drupal-watchdog.log-201510*.gz"

function getlogcounts {
    echo in getlogcounts
    echo  arg1: "$1"
    echo  arg2: "$2"

    ssh  $1 "cd "$2"; pwd; echo "$logfilepattern" ; for f in "$logfilepattern"; do  echo "$f"; done"
}

server="me@myremoteserver.com "
logdir="/var/log/mylogs"
getlogcounts $server $logdir 
  • You need to escape it. Use \$f. – jordanm Oct 5 '15 at 4:28
  • for f in "$logfilepattern"; do echo "\$f"; done can be replace by ls "$logfilepattern" – snoop Oct 5 '15 at 4:45
  • the echo is just a simple example. he said yesterday he wanted to zcat the matching files or something like that – cas Oct 5 '15 at 4:52
  • Yes... inside the do is actually a zcat $file | wc -l and some other stuff to split up the file name. – Max Oct 5 '15 at 4:57
  • Woot!! It works now. Adding the \ before $f did the trick with out without the bracketing "\"". Thank you @cas and @snoop! This has had me stumped for quite a while this weekend so really appreciate your prompt and effective help. – Max Oct 5 '15 at 5:01
1

If you want to include double-quotes inside double-quotes, then you have to

  • end the current double-quoted string: "
  • escape a double quote: \"
  • start the double-quoted string again: "

In other words: "\""

Ditto for including single-quotes inside single-quotes: '\''

You also need to escape $f with \$f as it only exists inside the quoted string script.

ssh  $1 "cd "\""$2"\""; pwd; echo "\""$logfilepattern"\"" ; for f in "\""$logfilepattern"\""; do  echo "\""\$f"\""; done"

Which looks very ugly and is very hard to read and/or debug.

In this particular case, as you are controlling the input to your function and can be reasonably sure you're not going to give it any dodgy values (including filenames with spaces), you can get rid of the double-quotes if you want. Except for "$f", unless you are absolutely certain that there will be no files matching $logfilepattern that contain spaces or other problematic characters.

ssh $1 "cd $2; pwd; echo $logfilepattern ; for f in $logfilepattern; do  echo "\""\$f"\""; done"

If the input comes from a user somehow, e.g. on the command line or from an environment variable (esp. incl. CGI env vars), then you have to (well, should) revert to the defensive style of quoting all variables.

  • I tried the "\"" around $f to no avail. I can see that pwd confirms I'm in the right (remote) directory and that echo $logfilepattern lists the expected 4 files. But the echo "\""$f"\""returns 4 blank lines (one for each file). – Max Oct 5 '15 at 4:54
  • did you escape $f as \$f. unless you do that, the local shell will insert the local value of $f (probably nothing). – cas Oct 5 '15 at 4:59
  • also, looking at your script again, you shouldn't double-quote $logfilepattern on the ssh command line at all, not even with "\"" - you want that to work as a glob on the remote host, which wont happen if you quote it. – cas Oct 5 '15 at 5:01
0

You can try the following code:

#!/bin/bash  
logfilepattern="drupal-watchdog.log-201510*.gz"

function getlogcounts {  
    echo in getlogcounts  
    echo  arg1: "$1"  
    echo  arg2: "$2"  

    ssh  $1 "/bin/bash -c ' cd "$2"; pwd; echo "$logfilepattern" ; for f in "$logfilepattern"; do  echo \"\$f\"; done'"
}  

server="me@myremoteserver.com "  
logdir="/var/log/mylogs"  
getlogcounts $server $logdir   

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.