Bash Command Substitution on Remote Host

Command substitution doesn't work in script text passed over SSH

$(ls -A $test_dir) is being executed locally on the client, not the server. You need to escape the $. You'll also need to use " around it, otherwise the command substitution won't be executed.

    if [ \"\$(ls -A $test_dir)\" ]; then

Often the best way to execute multiline commands is to use scp to copy a script to the remote machine, then use ssh to execute the script. Mixing local and remote expansion of variables and command substitutions gets complicated, especially when you need to quote them.

SSH command execution/variable substitution issue

If I understand this correctly, you are getting the variable ${USER} from the host (local) machine not from the SSH (remote) server. This is because you are executing it all in one command. Your command is being processed locally - meaning the variable is being substituted - before being sent to the remote (SSH) server.

You can solve this by passing the command as a string that will not be translated/processed/substituted locally to, in your case, firstuser, or whichever other previously declared variable.

firstuser@mymachine> ssh testuser@mymachine 'echo ${USER}'

Important note here is that echo ${USER} is in single quotes, it will not work with double quotes. This is basic bash/shell rule but as a courtesy, you can find out more about this at https://missing.csail.mit.edu/2020/shell-tools/#shell-scripting

In a nutshell, when a variable is being processed/interpreted/substituted locally as you are trying to do, the remote SSH server receives the litteral: echo firstuser not echo ${USER}, which would be processed remotely, as intended.

Remote command substitution fails

You are trying to pass a kill command to a server over ssh.

Unfortunately, all substitutions are done on the host side, and not the server side. The error you are getting from cat is an error which is generated on den16 and not BUILD_HOST. If you want to pass it to BUILD_HOST you have to use a pipe in this case. Normally you would use single quotes, but since you use shell variables already in there, you have to use a pipe

rundeck@den16 ~]$ ssh ${SSH_USER}@${BUILD_HOST} "cat ${WLS_E1DOMAIN_LOC}/nodemanager.process.id | xargs kill -9"

Bash command substitution on remote host

Use <<'EOF' (or <<\EOF -- quoting only the first character will have the same effect) when starting your heredoc to prevent its expansions from being evaluated locally.


BTW, personally, I'd write this a bit differently:

#!/bin/sh -e
ssh "$1" bash <<'EOF'
{ read; read container _; } < <(docker ps)
docker stop "$container"
EOF

The first read consumes the first line of docker ps output; the second extracts only the first column -- using bash builtins only.

bash variable substitution from remote command using sed

Parameters will not expand in single quotes, one can close them, and expand in double quotes instead:

ssh user@host 'sed "s/'"$localVar"'/replacement/" file'
^^
|Enter double quotes to avoid word splitting and globbing
Exit single quotes to expand on client side.

You should however know that the command send to the server is:

sed "s/abc/replacement/" file

Which might cause problems as we are now using double quotes on the server, one can send single quotes as well, but it quickly becomes as mess:

ssh user@host 'sed '\''s/'"$localVar"'/replacement/'\'' file'
^ ^
| Escaped remote single quote
Close local single quote

This will become:

sed 's/abc/replacement' file


Related Topics



Leave a reply



Submit