6

I essentially want to run a script on machine A which will SSH into machine B, execute commands on B, and return the output to machine A.

So I am creating a csh script to do this, hopefully, if it's possible.

For instance, this solution from this answer works from command line:

ssh user@host << 'ENDSSH'
ls -l
ENDSSH

I can verify it is running the ls on the remote and not locally.

However I want to be able to do this within the backticks, inside my csh script running locally. Would that be possible?

I know it is possible to SSH in and run a script that is on the remote, but that is not my case.

I have also heard it is possible to send a second script stored locally over the SSH (which I also have not figured out), but I like the idea of having all of the commands inside the original script, hence the HEREDOC.

I know it is a pretty particular question, but if there is a way, it would be very cool to know how.

Things that don't work

1)

`ssh user@host<<'ENDSSH'`
`echo "ls -l"`
`echo "ENDSSH"`

This gives the error:

stty: standard input: Invalid argument. stty: standard input: Invalid argument. Warning: Command not found

And then it runs ls -l locally, and then it tried to run ENDSSH locally and of course fails with command not found.

2)

`ssh user@host<<'ENDSSH'`
echo "ls -l"
echo "ENDSSH"

Same problem as above, except it only displays ls -l and ENDSSH as text. Makes sense...since the HEREDOC portion failed.

3) 3-5 aren't exactly what I asked about, but still trying just to get even the basic case working.

`ssh user@host ls-l` 

This returns total: Command not found. Yeah, I have no clue where that's coming from.

4)

`cat ./test.csh | ssh user@host`

Also returns the same as attempt #1

5)

`cat ./test.csh | ssh -t user@host`

Same as #1 and 4.

I am beginning to exhaust other solutions from stackoverflow/Ubuntu/serverfault...etc. Most people ask about how to run their script on a remote from command line, not how to run commands on a remote from a locally running script.

Edit

Well I think I have part of the problem figured out. With case 3 from above for example, what happens is ls -l runs locally, and the first part of the output is then sent over SSH as a command.

I noticed this because I tried ssh user@host $CMD, with $CMD set to "whoami". The output was username: Command not found, and then I realized the total is from the ls output. Still not sure about how to solve this, though

  • Have you tried ? I mostly use scp && ssh to check any problem with connectivity or password/ssh key. However your solution looks ok. – Archemar Mar 3 '15 at 18:40
  • @Archemar See the last section I have added. – krb686 Mar 3 '15 at 18:49
  • Re your Edit comment, that's not really correct. You have case 3 as ```ssh user@host ls -l` ``. What this does is run ssh user@host ls -l, which in turn runs ls -l on the remote host. The resulting output is grabbed by the backticks and evaluated locally, which because there's nothing to collect that output, ends up being executed as a local command. – roaima Mar 3 '15 at 22:30
  • @roaima Okay so I had it switched around, so it runs ls -l remotely, and the output locally, as opposed to ls -l locally, and the output remotely? – krb686 Mar 3 '15 at 22:39
  • Yes that's right. – roaima Mar 3 '15 at 22:49
3

If you wrap the entire command that you want executed inside backticks it's likely you'll get the correct solution. There are issues regarding the evaluation of variables and other interpolated elements, but I'll put those to one side for a moment.

However, I'm not entirely sure why you want anything in backticks. Your Question says you want to run a local script remotely. Your first example does this.

ssh -q user@host << ENDSSH
hostname
ls -l
id
ENDSSH

Perhaps you want to get the output of the remote execution into a variable? It doesn't say that anywhere in the Question, but you'd do it like this (bash)

RESULT=$(ssh user@host <<ENDSSH
hostname
id
ENDSSH
)
...
echo "$RESULT"

Or, since you mentioned csh, like this

set result = `ssh -q user@host` <<ENDSSH
hostname
id
ENDSSH
...
echo "$result"

Note that for the csh variant all output lines are concatenated together.

I see that you have reported an error, stty: standard input: Invalid argument. This is probably occurring because you have an stty command in your login script on the remote server. This should be wrapped in a test for an interactive shell. In bash you would do something like this:

if test -n "$PS1"
then
    # Interactive setup here
    stty ...
fi
  • Yes, you are correct I will eventually want to store the results of the commands run on the remote inside variables in the locally running script. Your csh solution is not working, unfortunately. This still results in errors: stty: standard input: Invalid argument. I added an edit to my question at the end with some interesting information, not sure if you saw that yet, but there is a clue. – krb686 Mar 3 '15 at 19:51
  • @krb686 Please see the update for stty. If you have the option, I would strongly recommend that you stop writing csh script and use sh/bash instead. There are a number of significant problems with using csh as a scripting language so it really would benefit you to learn sh/bash, even if you prefer csh for interactive use. – roaima Mar 3 '15 at 22:51
  • Ah I didn't see that. I will check that out in a minute. Thanks – krb686 Mar 3 '15 at 23:03
1

Not certain what your trying to do, but here is something that worked for me.

(drat having trouble keep stackexchange text editor from treating the back ticks as formatting characters, using forward ones for where I mean back ticks)

R='ssh -t hostname <<EOF
ls -l
EOF'

Note that I don't close the backtick until after EOF and use -t option to create a virtual TTY even though stdio is being redirected.

  • Hmm, so the input to the heredoc needs to be within the backtick. Now how do I separate those commands in the heredoc on separate lines of the csh script? This just complains about missing a backtick, since the backtick is started on the first line before ssh, and ended after EOF – krb686 Mar 3 '15 at 19:57
  • Okay so you need a "\" at the end of each line to continue the heredoc. Interesting, this almost works. It complains with: ls: cannot access EOF: No such file or directory. It thinks the EOF is an argument to whatever command is before it. Also tried this with whoami and it says whoami: extra operand EOF – krb686 Mar 3 '15 at 20:01
  • @roaima Thanks, I have been hearing that in multiple places. If you have a good reference, I'd like to read it! I have been learning (and prefer) bash, but I may potentially be forced to use csh for certain things. I am not entirely sure of that, though, and if there is a way to successfully do this with bash, I would definitely like that info as well, if anyone has it – krb686 Mar 3 '15 at 20:38
  • @krb686 we can't move comments. Just delete it and repost it at the right place. – terdon Mar 3 '15 at 22:06

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.