1

I'd like to capture the output of an ssh session. However, I first need to ssh twice (from my local computer to the remote portal to the remote server), then run a command and capture the output.

Doing this line-by-line, I would do:

ssh [email protected]
ssh remote.server.com
remote.command.sh

I have tried the following:

server=remote.server.com  ##define in the script, since it varies
sshoutput=$(ssh -tt [email protected] exec "ssh -tt ${server} echo \"test\"")
echo $sshoutput

I would expect the above script to echo "test" after the final command. However, the outer ssh prompt just hangs after I enter my command and, once I Ctrl+c or fail to enter my password, the inner ssh session fails (I believe since stdout is no longer printed to screen and I no longer get my password prompt).

If I run just the inner command (i.e., without "sshoutput=$(" to save it as a variable), then it works but (obviously) does not capture output. I have also tried without the "exec".

I have also tried saving the inner ssh as a variable like

sshoutput=$(ssh -tt name@portal myvar=$(ssh -tt ${server} echo \"test\"") && echo $myvar)

but that fails because BASH tries to execute the inner ssh before sending it to the outer ssh session (I believe), and the server name is not recognized.

(I have looked at https://unix.stackexchange.com/questions/89428/ssh-twice-in-bash-alias-function but they simply say "more flags required if using interactive passwords" and do not address capturing output)

Thanks in advance for any assistance!

6
  • 2
    The best approach here, by far, is to use ProxyCommand to have ssh itself do the work of setting up the inner ssh session. Commented Oct 27, 2016 at 20:21
  • Why are you using -tt? I'm not sure it makes a difference to this question, but it seems unnecessary. Commented Oct 27, 2016 at 20:23
  • @ ProxyCommand comment: something like the below link? My above remote.command.sh actually sets up a VNC server and returns which port (e.g., ":3") to use, then I ssh tunnel to that port. Will the commands in the below link interfere (and/or not have permission) with that? cyberciti.biz/faq/… Commented Oct 27, 2016 at 20:26
  • @cwotta, please include enough content to generate and test an answer in your question itself, as opposed to behind a link (particularly behind a cyberciti.biz link; I wouldn't touch that with a 10-foot pole). That said, in general, ProxyCommand usage doesn't interfere with other kinds of SSH proxy support. Commented Oct 27, 2016 at 20:27
  • @ why -tt: It appeared, through looking various sites, that it was necessary since I was double-ssh-ing. I would receive "not a real terminal"-type error (can't remember specifically), but it appears that it's no longer an issue because I just tested without it and it's no longer there, though my commands fail to execute. Commented Oct 27, 2016 at 20:31

1 Answer 1

2

The best-practice approach here is to have ssh itself do the work of jumping through your bouncehost.

result=$(ssh \
  -o 'ProxyCommand=ssh [email protected] nc -w 120 %h %p' \
  [email protected] \
  "remote.command.sh")

You can automate that in your ~/.ssh/config, like so:

Host remote.server.com
    ProxyCommand ssh [email protected] nc -w 120 %h %p

...after which any ssh remote.server.com command will automatically jump through remote.portal.com. (Change nc to netcat or similar, as appropriate for tools that are installed on the bouncehost).


That said, if you really want to do it yourself, you can:

printf -v inner_cmd '%q ' "remote.command.sh"
printf -v outer_cmd '%q ' ssh [email protected] "$inner_cmd"
ssh [email protected] bash -s <<EOF
$outer_cmd
EOF

...the last piece of which can be run in a command substitution like so:

result=$(ssh [email protected] bash -s <<EOF
$outer_cmd
EOF
)
Sign up to request clarification or add additional context in comments.

8 Comments

And if you always need to use the proxy to get to that remote server, you can put it into your .ssh/config.
@CharlesDuffy -- Update: I was incorrect. I'm using the first code block. It's NOT capturing the output into $result, it's just printing it to the screen (stdout) -- I initially thought it worked because I was echoing $result after, to check -- otherwise, it works (i.e., I'm able to log in and execute the command). Additionally, I tried the final two code blocks and immediately received three "permission denied" errors. This isn't important to fix, since I am not using that method, but thought I would note it.
Are you sure you're using the first code block as edited? The first version didn't capture at all (that was left as a -- rather obvious -- exercise to the reader).
...if it's still not capturing, chances are good that the content you're trying to grab are actually going to stderr, not stdout. Put a 2>&1 before the closing paren of the command substitution.
...as for the permission denied errors, use set -x to log the exact commands being run locally, and change bash -s to bash -x -s to do likewise for the remote bits. And post the output. I wouldn't be surprised if you had "remote.command.sh 'argument 1' 'argument 2'" when it needs to be "remote.command.sh" 'argument 1' 'argument 2' passed to printf, or similar; should be obvious when given the logs.
|

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.