SSH tips (and GNU screen)
Tags: tutorials, software, networking.
By lucb1e on 2014-05-10 17:29:00 +0100
Just a quick blogpost about some things for ssh that make my life easier. No more password typing, hostname, user and port remembering, or even losing your session when a connection drops. The latter didn't seem easy to find and I had to piece some things together, but I'll explain how to use ssh with gnu screen from step three onwards.
Configure an ssh host config if you haven't already. This is not necessary, but boy does it make things easier. Do you want to remember that you're supposed to connect as user vhost89103 to ssh.pcextreme.nl, as user oa to the gameserver on port 222, as user ... to whatever else? It's such a hassle.
The ssh config can be found in ~/.ssh/config. The .ssh folder does not exist by default. Use it like this:
hostname 192.168.1.57 # or a domain name, e.g. example.com
user root # optional
port 1234 # optional
ServerAliveInterval 60 # for if your connection randomly drops
Test it: ssh tel
SSH host keys. It's a debate whether they are more or less secure than passwords, but honestly, password management is a hassle best avoided if you can. To that end, let's use ssh host keys.
If you haven't got an ~/.ssh/id_rsa.pub file yet, create one with:
Just hit enter on all options, it's usually all fine. Passphrase is optional, you can use one if you're paranoid or do not have disk encryption. (Nothing against being paranoid by the way, there are often legitimate reasons to take extra precautions.)
Now that that's done, use the following command to make your remote host trust the key:
(Where 'tel' is the ssh host config you just made. Of course any user@hostname will work.)
Enter your password one last time, and you're all set! You can now connect to the host without entering a password. In fact, anyone with the .ssh/id_rsa file can connect to that host without entering a password, so be careful with it. If anyone ever asks for that file, they mean the id_rsa.pub file, never the id_rsa file.
Now that we have the basics, we want to use GNU screen. This was a hassle to setup, and honestly I'm not entirely sure why it works, but it works for me anyway.
Connect to the remote host and create a new file with the following contents:
if [ -t 1 ]; then
if [[ "$TERMCAP" != *screen* ]]; then
if [ $? -eq 1 ]; then
1. Check whether you're a terminal (prevent bothering rsync)
2. Check whether you're in screen already
3. If not, try resuming an existing screen session.
4. If the last command (resuming screen) failed, start a new session.
If you have two concurrent connections, this will start two screen sessions. You can change the behavior to use only one screen session by changing "screen -r" into "screen -x". Which is fun, by the way, to see yourself typing in another window, but pretty useless beyond that. Hmm, unless you have multiple computers all of which should share the same session. Use as you like.
Almost forgot: make the file eXecutable with chmod +x $theFile
Update 2014-05-12: if needed, add startup_message off
to prevent that message from popping up all the time. (Original post from here.)
To check whether it works (and make sure you won't end up in an infinite screen-in-screen loop), now execute ./$theFile
(where $theFile is the file you just made and chmodded). It should start a new screen session unless another was already running. It does? Good. Now run it again while still in that screen session. It shouldn't do anything at all. Yes? Okay.
Modify your bash config file so it does this automatically. The ~/.bash_profile file seems to be what you need to modify for ssh (the .bashrc file does not always get executed). If it does not exist, just create it. It doesn't need executable permissions. Add the following to the file:
./$theFile && logout
And don't forget to replace $theFile with the file that runs the screen session. Why do we need this logout? Because else when you want to quit, you'll first quit the screen session and then get stuck in an ssh session. So to prevent you accidentally working in a non-screen session and to log you out in one try, we include this logout command.
The odd thing is that this is inside a script, and logout should only work from the shell. Maybe because the file is interpreted by bash on startup it's different, but I don't know. It works for me though.
Again, you can test this. Stuff like this is best tested with a second terminal, so that if you get stuck in something weird (like a screen-in-screen loop) you can always edit the file again in the original terminal.
We now have most that I wanted to tell you, but there are a couple small things that may come in handy too. For example my basic .bashrc or .bash_profile file consists of:
alias '..'='cd ..'
alias '...'='cd ../..'
alias '....'='cd ../../..'
alias '.....'='cd ../../../..'
alias ls='ls -CF --color'
Well, that last one is not something I usually have to include, but it needed to because this particular ssh server doesn't seem to like grep colors by default. Most terminals will use colors in grep without that line.
I don't know why the dots (..=cd ..) are not something default or widely used! It's a great thing to have really. Deep in code bases I often have to jump back lots of levels, and 'go four directories up' is no unnecessary luxury in my opinion.
And of course the common ls
typos. Also make sure ls is colored, and display folders with a trailing slash. I used to use 'cd <tab>' for this to see which ls results were files and which were folders, but this makes it easier.
Usually in terminals you can use shift+pgup/pgdn to scroll, but not in screen. In screen you need to type ctrl+a and then press the [ key to enter copy mode, which allows scrollback. I use escape to cancel it, but there seem to be more ways. To actually copy something, I usually select it and then hit the middle mouse button (press down the scroll wheel) to paste.
Another must-have from bash is ctrl+r, which is reverse incremental search. Press those keys and then type a command you previously used. Or some argument you previously used. For example ctrl+r "test" will match the last time you used "echo test".
And lastly it's nice to be able to work with bash's job handling. If you are editing a file in vim and just need to check a filename that you used a few commands ago, press ctrl+z (in normal mode, not insert mode) and you get back to a shell. To resume working in vim, use the "fg" command to put the suspended application in the foreground again.
Or if you are running a grep command and realize it'll take a while, use ctrl+z to suspend it and then bg (background) to make it run in the background. The output will be printed through what you are typing, but it's still better than waiting in my opinion.
To view running jobs, simply use jobs
. You can suspend/background as many as you like and use bg #number or fg #number. Without number, it takes the last-used one I think.
Hope this was useful! Of course everyone's working style differs and you may not like or use all of this, but at least some of it may be useful.
Update 2014-05-11 03:43 UTC+02:
Edited the script so that it checks whether you're on a terminal at all (if -t 1). My previous script broke rsync.