Shell questions - shell

In the following context : VisualVM over ssh
I try to execute the 2 following commands in a single script:
ssh -D 9696 john.doe#121.122.123.124
/usr/bin/jvisualvm -J-Dnetbeans.system_socks_proxy=localhost:9696 \
-J Djava.net.useSystemProxies=true
Having the 2 command like this does not work because the ssh command starts in an interactive mode, so the VisualVM is started after the ssh is closed (explicitly with an 'exit').
What could be a good way to solve that issue?
PS. I am running MacOS X.

try:
ssh john.doe#121.122.123.124 '/usr/bin/jvisualvm -J-Dnetbeans.system_socks_proxy=localhost:9696 -J Djava.net.useSystemProxies=true'

If I understand your use case properly, you want to setup port-forwarding with the ssh connection then the second command is run on the localhost which uses the forwarded port on the localhost. I think you could try the -f or -n options to ssh to achieve this. It does however require a command to be run on the remotehost. You could use a bogus command like echo &> /dev/null for that.
EDIT:
Something like this seemed to work in a naïve test:
ssh -f -D <port> remotehost <dummy_program_that_doesnt_quit>

This is best done using an SSH key and screen, so that we interact with and can close the SSH session.
I'm also presuming jvisualvm takes control of the terminal so that when it exits, we clean up the screen session. If jvisualvm detaches from the terminal, the script immediately jumps to cleaning up the screen session while jvisualvm is running.
ssh-add .ssh/key
screen -dmS sshproxy ssh -i .ssh/key -D 9696 john.doe#121.122.123.124
/usr/bin/jvisualvm -J-Dnetbeans.system_socks_proxy=localhost:9696 \
-J Djava.net.useSystemProxies=true
screen -r -d sshproxy -X quit

Related

SSH from Local to A, A to B and run multiple commands on B

Im currently using the line of script below to ssh from my local machine to a server (lets call it ip-address1) then from that machine i want to ssh to another machine (lets call this machine ip-address2). The script i use is as follows:
sshpass -p mypassword ssh -tt user#ip-address1 ssh -tt -i /root/.ssh/vm_private_key user#ip-address2 "pwd; ls;"
The problem is only the first command (pwd) executes on ip-address2 then it closes and the ls command executes on ip-address1 before it then closes. I want both commands to execute on ip-address2. The output in my terminal is something like the following:
/home/user (pwd command executing here)
Connection to ip-address2 closed.
//files then get outputted here (ls command executes after ip-address2 has
closed)
Connection to ip-address1 closed.
I think there may be something wrong with my quotation but i cant figure out what. Please help.
Thanks.
I don't have any way to test this, but try the following:
sshpass -p mypassword ssh -tt user#ip-address1 \
"ssh -tt -i /root/.ssh/vm_private_key user#ip-address2 'pwd; ls;'"
You definitely need to quote the entire command you want to run on the ip_address1, including the command you'll pass to ip_address2.
Edit
I'm in an environment where I have multiple machines to test; the following command works for me:
ssh snewell#<host sanitized> \
"ssh <host2 sanitized> 'hostname; ls -a <path sanitized>;'"
hostname definitely displays the result of the final server (host2), and ls is listing a directory that the first host doesn't have.

SSH: Run command through sub server

My goal is to be able to send a command to an old server that can only be
reached by going through the new server.
I want to be able to automate this as much as possible.
I want to be able to just run a script and it will do the work for me so
that I don't have to type.
Meaning I would have to do the following:
ssh user#newserver
and then
ssh user#oldserver
Once I reach the old server I need to be able to run
curl icanhazip.com
and
cat /var/spool/cron/user
So far I was only able to do the following:
ssh -t -t root#newserver "ssh root#oldserver"
That would only allow me to reach the server, but I would have to manually send other commands.
I would Ideally want to be able to run something like this:
ssh -t -t root#newserver 'ssh root#oldserver "cat /var/spool/cron/user"'
ssh -t -t root#newserver 'ssh root#oldserver "cat /var/spool/cron/user"'
This Actually worked. Not sure why it didn't before.

Run ssh and immediately execute command [duplicate]

This question already has answers here:
Can I ssh somewhere, run some commands, and then leave myself a prompt?
(5 answers)
Closed 7 years ago.
I'm trying to find UNIX or bash command to run a command after connecting to an ssh server. For example:
ssh name#ip "tmux list-sessions"
The above code works, it lists the sessions, but it then immediately disconnects. Putting it in the sshrc on the server side works, but I need to be able to type it in client side. I want to be able to run a command, it logs in, opens up the window, then runs the command I've set. Ive tried
[command] | ssh name#ip
ssh name#ip [command]
ssh name#ip "[command]"
ssh -t name#ip [command]
ssh -t 'command; bash -l'
will execute the command and then start up a login shell when it completes. For example:
ssh -t user#domain.example 'cd /some/path; bash -l'
This isn't quite what you're looking for, but I've found it useful in similar circumstances.
I recently added the following to my $HOME/.bashrc (something similar should be possible with shells other than bash):
if [ -f $HOME/.add-screen-to-history ] ; then
history -s 'screen -dr'
fi
I keep a screen session running on one particular machine, and I've had problems with ssh connections to that machine being dropped, requiring me to re-run screen -dr every time I reconnect.
With that addition, and after creating that (empty) file in my home directory, I automatically have the screen -dr command in my history when my shell starts. After reconnecting, I can just type Control-P Enter and I'm back in my screen session -- or I can ignore it. It's flexible, but not quite automatic, and in your case it's easier than typing tmux list-sessions.
You might want to make the history -s command unconditional.
This does require updating your $HOME/.bashrc on each of the target systems, which might or might not make it unsuitable for your purposes.
You can use the LocalCommand command-line option if the PermitLocalCommand option is enabled:
ssh username#hostname -o LocalCommand="tmux list-sessions"
For more details about the available options, see the ssh_config man page.

Running ssh sudo asynchronously

I'm trying to run a command with sudo on a remote machine. When I do it directly with
ssh -t -t -t myserver -q "sudo otheruser<<EOF
remotescript.sh
EOF"
it works fine, but if I add & at the end of the last line then it doesn't work. Why? How can I make it work?
I fact I'm running several such commands (to different servers) from a local script and save each output in a different file and would like them to run asynchronously.
Note: running ssh with otheruser#myserver is not an option. I really need to run sudo after I logged in.
Remove requiretty from sudo config (/etc/sudoers) on the remote machine.
Also add the -f option to ssh which puts the command in background (man: "must be used when ssh is run in the background").
The "&" should not be needed when using -f.
E.g:
ssh -f -t -t -t myserver -q "sudo otheruser<<EOF
remotescript.sh
EOF"
Use expect to control your ssh. It could be used to give automated response to the remote shell. Most processes when ran asynchronously suspends itself or becomes suspended when it tries to read input from terminal since another foreground process (the main shell) is using it.
There's a post about ssh and expect lately here: https://superuser.com/questions/509545/how-to-run-a-local-script-in-remote-server-using-expect-and-bash-script
Also try to disown your process after placing it on the background with disown to keep it from job control. e.g.
whole_command &
disown
Changing its input to /dev/null might also help but it could hang forever if it really needs input from user.
whole_command <&- < /dev/null &
disown

bash script to ssh into a box and get me to a python shell

I want to write a script that will get me straight to a python shell on another box so that i don't have to first run ssh and second run python.
When I do "ssh hostname python" it just hangs - it's something to do with the fact that python is interactive. "ssh hostname cat x" works fine.
Is there some ssh option that will make this work?
ssh -t user#host python
The -t flag forces ssh to allocate a pseudo-terminal to the connection. Normally it won't do this if a command is given on the ssh command line, which results in python running in a non-interactive mode.
actually figured it out, i needed to do ssh -t hostname python
You need the -t option to force the allocation of a pseudo-tty
ssh -t host python

Resources