I am having a problem working with SSH in Unix to run a script on a remote machine. The script is meant to run infinitely until an event happens, in which case it will then break out of its loop. Unfortunatly it seems that after a short peroid of afew secounds the script stops running. I 开发者_C百科believe this is related to SSH as the script when ran localy works as intended.
Is there a way I could trigger my remote machine to run that script as if it was being ran locally, so that I could close the SSH conneciton and it would still be running?
The script that calls the script located on the remote machine is this.:
#!/usr/bin/expect set add [lindex $argv 0] set add2 [lindex $argv 1]
spawn ssh -l root2 ${add} /home/jason/localCopy/selfMonitor &
expect *assword: send "BIGMASSIVESECRET\r"
expect "]$ "
Contained in the selfMonitor script is basically a do while true statement that will run forever until broken.
Any help is appreciated, thanks.
Yes, you can do this using screen
- Log in to remote machine
- Start a new screen session by typing:
screen
- Then run your script as normal:
./myscript
- Then, to detach:
Ctrl-A, D
To reattach later, log in to the machine, and run screen -r
to reattach to the running session.
Use nohup
to have your script ignore SIGHUP, which is sent to backgrounded processes when the parent shell exits.
spawn ssh -l root2 ${add} nohup /home/jason/localCopy/selfMonitor &
Also, ssh intentionally makes it difficult to script the password entry and you are encouraged not to work around this behavior. The right way to allow password-less ssh access is to use pre-authorized keys.
- Run
ssh-keygen
on the client. You can press enter at all the prompts to use a blank password. - Add the contents of
~/.ssh/id_rsa.pub
to the end of a file called authorized_keys on the server:root2@server:~/.ssh/authorized_keys
.
Creating a key and then adding it to authorized_keys allows the client to connect to the server without using a password, and it lets you do it without hard coding a password into a plaintext script.
To make your script run forever you need to do two things
- Make sure you don't write to the terminal. Close it or redirect it stdout and stderr, and close stdin. If you don't they'll keep the SSH open, and / or cause your script to terminate on a broken pipe.
- You need to trap SIGHUP which is sent to your process when the terminal disconnects, and normally results in the script terminating.
This is done differently in different languages, so for your language of choice, you need to look it up. In bash you use exec >logfile 2>&1
to redirect both stdout and stderr to logfile, and trap "" HUP
to ignore the HUP signal. If you can, start a new process group as well, to reset the parent pid to init (officially making it a daemon process).
If you need to access the terminal output from the script (and can't redirect for whatever reason), may I recommend screen.
Another approach is to demonize the script so that it detaches itself from the IO streams connected to SSH and starts a new session on startup.
Here there is a nice HOWTO.
And if your script is programmed in some popular language as Perl or Python, you will be able to find modules to do it.
Although solutions here are valid, I've started using tmux
extensively for such tasks.
You will be able to start a session, detach and reattach anytime you want. You can disconnect from your remote machine and it will still be running. Sessions can even have multiple windows, etc.
If you have 10 minutes, try this simple guide to tmux
: A Quick and Easy Guide to tmux
After going through the guide, I've written a small cheatsheet that was in front of me for a day or two, but it's now almost a second nature to me. I've been using tmux for other tasks such as running a backend server in one pane, frontend in the other while having another pane just for usual terminal business. When you're done with working on a certain project, you can just detach and attach to another session to continue where you left off.
精彩评论