0

I need to use a variable within a backtick expression embedded in a rcp invocation.

My initial attempt:

#!/bin/sh
release=1
rcp myserver.foo.com:'`ls -t /path/to/my/${release} | head -n 1`' .

I suppose this is failing because the back-tick expression is being executed on myserver.foo.com which doesn't have a release variable, so the argument to my ls command is just /path/to/my/.

I read that typically the eval command can be used to (I think) pre-process the back-tick expression. When I try that approach:

#!/bin/sh
release=1
rcp myserver.foo.com:'`ls -t /path/to/my/eval ${release} | head -n 1`' .

...the backtick expression is just executed as /path/to/my/eval.

How I can use variables in my backtick expression in this context?

To be clear: I'm attempting to have the code in back-ticks run on the remote server, not locally (but I need ${release} to be resolved locally before-hand)

Community
  • 1
  • 1
Jonathan.Brink
  • 23,757
  • 20
  • 73
  • 115

1 Answers1

1

To run the ls on the remote, but expand $release to its value on the local machine, you need to use different quotes. To make the variable $release be exanded locally, it needs to be in double quotes, rather than single. You can accomplish that with:

#!/bin/sh
release=1
scp myserver.foo.com:'$(ls -t /path/to/my/'"${release}"' | sed 1q)' .

If there are unusual characters (eg, whitespace) in the file names, you will probably want to add more quotes:

scp myserver.foo.com:'"$(ls -t /path/to/my/'"${release}"' | sed 1q)"' .

Note that you probably want to add the full path:

scp myserver.foo.com:/path/to/my/"$release"/'"$(ls -t /path/to/my/'"${release}"' | sed 1q)"' .
William Pursell
  • 204,365
  • 48
  • 270
  • 300
  • Thanks, but does the first `$` need to be escaped (`\$`)? It worked after I escaped it... – Jonathan.Brink Jul 13 '16 at 14:13
  • The first `$` should not need to be escaped. – William Pursell Jul 13 '16 at 14:15
  • It seems that the solutions you posted are causing the previously back-ticked command to be run locally, rather than on `myserver.foo.com`. But if I escape the `$` character it works...so thanks! You got me past my hurdle! – Jonathan.Brink Jul 13 '16 at 14:20
  • It's a little misleading to simply say to change the "spelling"...I understand that rcp should be considered legacy next to scp, but that is the technology that happen to be using in this scenerio... – Jonathan.Brink Jul 13 '16 at 14:21
  • Also a question...(probably a noob question), is there a reason why `sed` would be considered superior to using `head` in this case? – Jonathan.Brink Jul 13 '16 at 14:22
  • No reason to prefer sed, it's just a personal preference. Yes, the process substitution runs on the local machine. By escaping the `$`, you are causing it to run on the remote (unless you include the embedded single quotes!) To run on the remote, it's probably easier to do `rcp myserver.foo.com:'"$( ls -t /path/to/my'$release'| head -n 1)"'` – William Pursell Jul 13 '16 at 16:09
  • Ah, gotcha. Yes, I was trying to have the back-tick expression run on the remote server (that may not have been clear from my original question, which I have updated). If you update your answer to reflect this change, I'll test it and mark your answer as correct. Thanks for your help!!! – Jonathan.Brink Jul 13 '16 at 16:17
  • Updated to invoke ls on the remote. – William Pursell Jul 13 '16 at 20:44