Script Stops after doing SSH - ssh

When I am doing SSH to some machine inside the for loop it is doing the ssh but not able to execute further.
Code is like:
string=c01.test.cloud.com,c02.test.cloud.com
for i in $(echo $string | sed "s/,/ /g")
do
ssh -t -t AppAccount#$i
cd a/b/c
str2=x,y,z
done

I take it from your question that you expect cd a/b/c to run on a remote server? That's not what this script is doing. The call to ssh opens an SSH tunnel, and provides you an interactive terminal connection. It then waits for that connection to terminate. (I suspect if you pressed Control-D, the script would continue.) Your use of -t -t here is particularly strange. Why do you want to force a remote pty? This is making the problem worse (not that much, since it won't work anyway, but this seems the opposite of what you'd want).
I think this is the script you meant:
string=c01.test.cloud.com,c02.test.cloud.com
for i in $(echo $string | sed "s/,/ /g")
do
ssh AppAccount#$i 'cd a/b/c; str2=x,y,z'
done
(This won't do anything of course, but I assume your real script has more to it than setting a shell variable and exiting.) The point is that you ned to pass the script you want to run as a parameter to ssh. Otherwise it's going to spawn an interactive shell and wait for you to close it.
Note that if your script is very complicated, it can be very inconvenient to stick it all in a single-quoted string. If your internal script is in its own file, a simple way to handle this is with bash -s which reads a script from stdin:
cat some_script | ssh server 'bash -s'
You can also use bash Here docs to achieve the same thing, but that is likely getting too fancy for this use.

Related

Unable to exit from SSH when executed from TCLSH

I have hard requirement of logging into a terminal via SSH from TCL console and relaunch a tcl script from that terminal. For this I use exec command and it does get executed. The only problem is it doesn't return back to parent code.
I have automated SSH login and it works fine from a bash/csh terminal
But from TCL console, the following happens
Simple example
exec ssh hostname pwd
puts "Done"
When I execute this code in TCL, "Done" never gets printed. I just get the output of pwd and that's it.
I have a need of looping SSH into multiple terminals and run TCL jobs on a hardware, but the loop gets stuck after executing the first SSH.
I search the internet for answers and I am not able to find any. Please help.
There could be a lot issues going on here. Running ssh with an explicit command (pwd) will usually default to not allocating a tty (ssh -T) and will run the remote shell in non-interactive mode. And the output of a command called from exec is not normally echoed to standard output, so I would not expect you to see the output if you call it from a script. You have to print the result of exec to see the output of the pwd command. Also, different shell startup scripts are run on the remote host depending on which shell the account is set up with and whether it is an interactive or non-interactive shell. It could be .bashrc, .bash_profile, .profile, .cshrc, etc., and if the script behaves differently when it has a tty vs. when it doesn't, that could explain differing behavior between a bash/csh shell and the TCL console.
Without having access to your system, it is hard for me to troubleshoot. I would start with a script like this:
set result [exec ssh -T hostname pwd]
puts "result = $result"
puts "Done."
Then I would try changing the -T to a -t and trying again. If the output of "pwd" is appearing before the "result =" line, then you can tell that the command is writing the result to a tty instead of standard output, and that's useful information for troubleshooting.

Run interactive local script on remote machine using docker-machine ssh

I have a local interactive (ruby) script, script.rb. I have a dockermachine, aws01. (The script pulls large files from point A, does some simple processing, and uploads them to S3).
Unfortunately, this incantation doesn't seem to do it:
docker-machine ssh aws02 -t ruby < script.rb
It runs the script, but not interactively :/
Any ideas how to do this in a single command?
(You could copy the script over and run it, you could grab the docker-machine's info and plug it into SSH with the -t flag... but I don't know how to do that in a single command)
You are putting the script itself on the standard input of the remote command (< redirection) so there is no other channel left for you to interact with the script.
In short, it is not possible with a single command. I would go with two:
docker-machine ssh aws02 "cat > script.rb" < script.rb
docker-machine ssh aws02 -t "ruby script.rb"

Transfer files over SSH, then appended to another file

I'm trying to automate a script that copies a file from my local server to a remote server on the command line. I've done the research on scp and know how to copy the file to the remote server, but then I want to append that file to another.
This is my code:
scp ~/file.txt user#host:
ssh user#host cat file.txt >> other_file.txt
When I enter everything into the command line manually as such, everything works fine:
scp ~/file.txt user#host:
ssh user#host
cat file.txt >> other_file.txt
But when I run the script, only the file is copied, not appended to the end of other_file.txt. Help?
The second line of your code should be
ssh user#host "cat file.txt >> other_file.txt"
Three important points:
You don't want your local shell to interpret >> in any way (which it does if it's unquoted)
There is a remote shell which will interpret >> in the command correctly.
Final arguments to ssh are "joined" to form a command, not carried into an argv array as they are. It may be convenient but it also may lead to confusion or bugs: ssh cat "$MYFILE" and ssh "cat '$MYFILE'" both work in a common use case, but they both break for different values of $MYFILE.
You need to enclose the command to be run on the remote host in quotes. Otherwise, the redirection is being done locally rather than remotely. Try this instead:
scp ~/file.txt user#host:
ssh user#host 'cat file.txt >> other_file.txt'
Try this:
$ cat file.txt| ssh hostname 'cat >> other_file.txt'

How to inject commands at the start of an interactive SSH session?

I want to be able to just ssh to a server where I cannot modify profiles and set up the environment with several commands before getting the usual interactive session.
Any ideas?
I've been using an expect script with an "interact" command at the end - which works for most things but is clumsy and breaks some console apps. Also been extermienting with empty-expect and socat. Any other suggestions?
If you're able to write somewhere on the filesystem, you may be able to invoke bash with a custom rc file like this:
ssh me#example.com -t bash --rcfile /home/user/my_private_profile -i
Note that this appears to only work for interactive shell, not login shells. The -t option to ssh makes it allocate a pty even though you're specifying a command.
If you can't write to the filesystem anywhere, you could use a subshell to supply a named pipe as the rcfile:
$ ssh ares -t "bash --rcfile <(echo 'FOO=foo';echo 'BAR=bar') -i"
axa#ares:~$ echo $FOO
foo
axa#ares:~$ echo $BAR
bar

running command on remote machine using ssh

i want to run some command on several machine using ssh. I know it can be done by just using the command "ssh user#hostname command". However, the command i want to run print some string on the console. Is there any way that send all the strings back to the console that i'm on?
You could run the commands in a screen:
screen -S test
ssh user#hostname command1
ssh user#hostname2 command2
You can then detach (Ctrl-D) from the screen, let it run for however long it will run, then re-attach (screen -r test) to the screen and see all of the output. This assumes that you won't have a ton of output from the commands, however. Here's a link to a tutorial on screen.
ssh user#hostname command
Does just that. if 'command' outputs something, it'll show on the terminal you ran ssh from.
Try e.g. ssh user#hostname ls -l
But as others have said, GNU screen is invaluable for this type of work.
You probably want to use Gnu Screen for this. You can start a process in a "virtual" terminal, "detach" the terminal and log out for however long you want... Then you can ssh back in and re-attach the terminal to see the console output.
Also have a look at nohup, for example:
ssh user#domain.com nohup script_that_outputs_strings.py > the_strings.txt
Then if you want to go back and monitor the progress, you could check back and tail the file or scp the output back to your local machine.
Why don't you send you an email back?
Or use a log file, and scp it to your current computer?
otherwise, I don't know!