Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!

Another way to create quick-access SSH shortcuts UNIX
I was initially using SSH shortcuts as described in this hint, but after using the hint for a while, I noticed some problems:
  • There doesn't seem to be a way to create .inetloc files other than drag and drop. You can create a file that has the correct data fork and the Finder will handle it, but without the resource fork portion that the Finder itself creates upon drop, other programs (like Path Finder) won't open the file properly. I keep a list of hosts I regularly connect to in ~/.hosts, and I wanted to be able to use a script to create the .inetloc files based on .hosts, rather than have to drag and drop the location to the Finder for every single one. (That would be fine if it was one time only, but the list changes.)
  • For whatever reason (I suspect a bug in Terminal.app), if you open a new Terminal window via one of these ssh://host shortcuts, .term files will not open until you relaunch the Terminal. They'll make Terminal the active pplication, but nothing happens.
  • For whatever reason (another bug?), windows opened via the ssh://host .inetloc files don't show the "Command key" (⌘1, ⌘2, etc) in the window's title bar. (Although the command keys still work if you're a good guesser.)
  • The ssh:// addresses don't allow for many SSH options. From what I can tell, username is the only thing you can change, and even that can be problematic as robg pointed out.
  • I had to tell QuickSilver where to look for the .inetloc files, but I noticed that it already indexes ~/Library/Application Support/Terminal/ by default.
The solution was to use .term files for everything instead of ssh:// shortcuts.

My original objection to doing this was that .term files include every available Terminal setting. I like the ssh:// shortcuts because they would connect to a specific host, but use my default Terminal settings. By using .term files, I would have to recreate every single one to match the default settings if they ever changed …or so I thought.

It turns out that you can create a bare-bones .term file that contains only the settings you want to change from the defaults, and the Terminal will know what to do with it. In this case, I just wanted to specify the command that gets run in the new Terminal window. The script linked below will scan ~/.hosts and create a .term file for each machine listed there in ~/Library -> Application Support -> Terminal. I used PHP because that's what was quickest for me, but this wouldn't be hard to implement in other languages.
  1. Download the script [macosxhints mirror]
  2. Unzip the script and put it somewhere in your $PATH.
  3. Create ~/Library/Application Support/Terminal/ if it doesn't exist.
  4. Create a file in your home directory called .hosts and add the hostnames of machines you want to connect to (one per line).
  5. Run the mkterms script
Now you can access all these Terminal sessions by going to File -> Library in Terminal (after a relaunch), or better yet, using your favorite launcher-type thing (QuickSilver, LaunchBar, Butler, etc).

You could modify the script to add other options to the "shell command", such as a custom identity file or a different username. For example, the version I use is smart about how and when it creates .term files for root based on an LDAP database of machines we have where I work.
    •    
  • Currently 2.00 / 5
  • 1
  • 2
  • 3
  • 4
  • 5
  (4 votes cast)
 
[13,025 views]  

Another way to create quick-access SSH shortcuts | 17 comments | Create New Account
Click here to return to the 'Another way to create quick-access SSH shortcuts' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
Another way to create quick-access SSH shortcuts
Authored by: toppledwagon on Oct 16, '06 09:22:04AM

Maybe I'm missing something, instead of creating a .hosts file, could you just scan ~/.ssh/known_hosts?

-Dave



[ Reply to This | # ]
Another way to create quick-access SSH shortcuts
Authored by: Skurfer on Oct 18, '06 10:05:32AM

A couple of reasons. known_hosts is a list of machines I've already connected to. I need a list of machines I have access to or may need to connect to some day. Also, known_hosts is machine specific, but I need the list on several machines and .hosts is safely portable.

I should also mention that my shell (tcsh) uses .hosts, /etc/hosts.equiv and others for tab completion. For example, if I type "ssh blah" or "ping blah" then start doing tab completion, it will use the list of hostnames instead of file names. With some work, I could get tcsh to understand known_hosts, but it's easier to use a bunch of files that are in the same format.



[ Reply to This | # ]
Another way to create quick-access SSH shortcuts
Authored by: joose on Oct 16, '06 10:20:10AM

Here is one idea, read hosts from config-file.

Here is example entry from ~/.ssh/config:

host gw
hostname 192.168.11.1
user notmyname
Compression no
ForwardX11 no

and now: "open ssh://gw/" opens connection to 192.168.11.1 with username notmyname and using nocompression and no x11 forwarding. Several other options also exists. ProxyCommand is one of the ones I like to get pass the firewall.

here is a patch from original file:


30c30
< $host_list = "$home/.ssh/config";
---
> $host_list = "$home/.hosts";
55,57c55,58
<       $hostA=explode(" ", $host);
<       if ($hostA[0] != "hostname") {
<               continue;
---
>       make_term( $host );
>       // root access .term file
>       if ( $create_root_terms ) {
>               make_term( $host, "root" );
59d59
<       make_term( $hostA[1] );



[ Reply to This | # ]
Another way to create quick-access SSH shortcuts
Authored by: joose on Oct 16, '06 10:21:50AM

of course that one line should be != "host" and not != "hostname"



[ Reply to This | # ]
Another way to create quick-access SSH shortcuts
Authored by: mtimmsj on Oct 16, '06 11:00:20AM

Minor quibble: You can create .inetloc files without drag and drop using the "Connect to Server" menu option (command-k) in finder.

For the server name simply enter ssh://username@host/ or just ssh://host/ if you are using an ssh config file (for example), then click the + icon to add it to your favorites.

Also they are just Property List files so you could even create them without the finder, it's just XML.



[ Reply to This | # ]
Another way to create quick-access SSH shortcuts
Authored by: Skurfer on Oct 18, '06 09:55:57AM
Minor quibble: You can create .inetloc files without drag and drop using the "Connect to Server" menu option (command-k) in finder.

For the server name simply enter ssh://username@host/ or just ssh://host/ if you are using an ssh config file (for example), then click the + icon to add it to your favorites.

Good to know. If that functionality can be accessed via AppleScript, then it might have come in handy for me, but there's still the problem where .term files won't open after an ssh:// address has been used.

Also they are just Property List files so you could even create them without the finder, it's just XML.

Yes, the data fork contains XML, but there is also (redundant?) information in the resource fork. Like I said, only Finder seems to accept the XML portion of the file. Other apps seem to rely on the resource fork and can't use .inetloc files if it doesn't contain the right voodoo.



[ Reply to This | # ]
Another way to create quick-access SSH shortcuts
Authored by: mtimmsj on Oct 18, '06 11:18:49AM
For applescript there is no need to use an .inetloc file. Simply use:

open location "ssh://username@host/"


[ Reply to This | # ]
Another way to create quick-access SSH shortcuts
Authored by: Skurfer on Oct 19, '06 07:12:19AM

I meant the ability to make the .inetloc via AppleScript, not the ability to connect.



[ Reply to This | # ]
Another way to create quick-access SSH shortcuts
Authored by: sbartram on Oct 16, '06 01:01:15PM

Is there a way to change the app used to open ssh:// URLs from Terminal to something else like iTerm?



[ Reply to This | # ]
Another way to create quick-access SSH shortcuts
Authored by: jaysoffian on Oct 16, '06 03:48:47PM

This is handled by OS X's Launch Services. Google for "Default Apps" (with the quotes), download the preference pane, install it, activate it, then seelct URLs, scroll down to ssh, and change the Default Application for ssh from Terminal to iTerm.



[ Reply to This | # ]
Another way to create quick-access SSH shortcuts
Authored by: gshenaut on Oct 16, '06 07:01:23PM
My solution to getting easier CLI access to my various systems is to use xterm instead of Terminal. There is an X11 "Applications" menubar item that allows customizable menu items. I simply enter the command needed to open an xterm window via ssh (or with some of my older machines, telnet) and when I need access to one, I just click it. For example, here's an expurgated version of one of the commands in my current X11 Applications menu:

xterm -T SOME -n SOME -bg Red -e ssh -X -lsomelogin some.domain.name

Of course, this assumes that the xterm program is installed on each system I access this way.

Greg Shenaut

[ Reply to This | # ]

Another way to create quick-access SSH shortcuts
Authored by: gshenaut on Oct 16, '06 07:05:49PM

I take back that last comment. I don't think xterm has to be on the remote system.

Greg Shenaut



[ Reply to This | # ]
Another way to create quick-access SSH shortcuts
Authored by: tvon on Oct 16, '06 08:47:20PM

My (current) method of choice:

1- Open Terminal "Connect to Server" dialog
2- Open SSH connection to server of choice
3- (optional) Open the "Window Settings" window and give the window background a slight color tint
4- Hit command-S and save the .term file (with hostname as filename)

Open new sessions with the File->Library menu



[ Reply to This | # ]
Another way to create quick-access SSH shortcuts
Authored by: bunam on Oct 17, '06 06:27:08AM
http://iterm.sourceforge.net/

tab terminal + shorcut + more + more

[ Reply to This | # ]
(Rewrite) Another way to create quick-access SSH shortcuts
Authored by: GaelicWizard on Oct 18, '06 10:47:48PM
Fantastic hint. I've taken the time to rewrite portions of your script, adding some extra features. My new version allows for specifying username and port in the .hosts file. In adding this support, I've changed a few things with regard to $term_file, so that different user names to the same host don't clobber each other; ditto for ports. Enjoy! JP P.S. This has already been formatted and should be A-O.K. to just select, copy, and paste. The original poster named the file "mkterms.phps" and have kept that name. You might like it too. :-) JP

#!/usr/bin/php
<?php

/*
This script has been adapted and improved by John Pell.
My changes are hereby released into the public domain.

18 Oct 1006
 - changed make_term($host,$access) to make_term($host,$user), which is basically what it already was.
 - removed special cases for root, which would take twice as long since it made a non-root file, then overwrote it, and isn't useful.
 - extended .hosts format to allow for specification of user name
    = the user name MUST be separated from the hostname by a TAB character
 - extended .hosts format to allow for specification of port number
    = the port number MUST be separated from the user name by a TAB character
    = for a port number, but no user name, use `hostname{TAB}{TAB}port'
*/

/* by Rob McBroom

This script will scan a file called .hosts in your home directory and generate
files that can be used by the Terminal application in Mac OS X to connect
directly to each machine.

If a host is listed in .hosts, a hostname.term file will be created that runs:
		/usr/bin/ssh hostname

!!! WARNING !!!
* Existing files will be overwritten
* .term files for hosts that no longer appear in .hosts will be
  removed by this script.

*/

/*** You shouldn't need to mess with stuff below this line ***/
$home = $_ENV['HOME'];
$username = $_ENV['USER'];
$host_list = "$home/.hosts";
// be sure to include trailing / after $terminals_folder
$terminals_folder = "$home/Library/Application Support/Terminal/";
// XML comment to identify files generated by this script
$mkterms_tag = "<!-- generated by mkterms -->";

if ( !file_exists( $terminals_folder ) ) {
	echo "Couldn't locate the directory for storing Terminal files.n";
	echo "Please create "$terminals_folder" and try againn";
	exit;
}

if ( !file_exists( $host_list ) ) {
	echo "Couldn't locate the list of hosts.n";
	echo "Please add a list of hostnames to "$host_list" and try againn";
	exit;
}

// preparation for cleanup
$created_terms = array();
$existing_terms = list_my_terms();

$hosts = array_map( "rtrim", file( $host_list ) );
foreach( $hosts as $host ) {
    $host = explode ("t", $host);
    $hostname = $host[0];
    $username = $host[1];
    if ($host[2] != "")
        $port = $host[2];
    else
        $port = "22";
    
	// basic SSH .term file
    make_term( $hostname, $username, $port );
}

echo count( $created_terms ) . " .term files were generated.n";

// do cleanup
$obsolete_terms = array_diff( $existing_terms, $created_terms );
if ( count( $obsolete_terms ) > 0 ) {
	echo "The following obsolete files are being removed:n";
	foreach( $obsolete_terms as $obsolete_terminal ) {
		echo "  $obsolete_terminaln";
		unlink( $terminals_folder . $obsolete_terminal );
	}
}

function make_term( $host, $user = "nobody", $port = "22" ) {
	// write a terminal file for this host

    if ($host == "")
        return;
	
	if ($port == "22")
	   $ssh_port = "";
    else
        $ssh_port = "-p $port";
	
	global $terminals_folder, $mkterms_tag, $created_terms;
	
	switch ( $user ) {
		case 'nobody':
			$shell_cmd = "/usr/bin/ssh $ssh_port $host";
			$term_title = $host;
		break;
		default:
			$shell_cmd = "/usr/bin/ssh -l $user $ssh_port $host";
			if ($port != "22")
                $term_title = $user."@".$host.":".$port;
			else
                $term_title = $user."@".$host;
		break;
	}
	$tfp = fopen( $terminals_folder . "$term_title.term", 'w' );
	$term_settings = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
$mkterms_tag
<dict>
	<key>WindowSettings</key>
	<array>
		<dict>
			<key>Shell</key>
			<string>$shell_cmd</string>
			<key>CustomTitle</key>
			<string>$term_title</string>
		</dict>
	</array>
</dict>
</plist>

XML;
	fwrite( $tfp, $term_settings );
	fclose( $tfp );
	array_push( $created_terms, "$term_title.term" );
}

function list_my_terms() {
	// index .term files previously created by this script
	global $terminals_folder, $mkterms_tag;
	$my_terms = array();
	if ( $td_handle = opendir( $terminals_folder ) ) {
		while ( ( $term_file = readdir( $td_handle ) ) !== false ) {
			if ( preg_match( "/.term$/", $term_file ) ) {
				if ( in_array( $mkterms_tag, array_map( "rtrim", file( $terminals_folder . $term_file ) ) ) ) {
					// this .term file was generated by this script
					array_push( $my_terms, $term_file );
				}
			}
		}
		return $my_terms;
	}
	return false;
}

?>

---
Pell

[ Reply to This | # ]

(Rewrite) Another way to create quick-access SSH shortcuts
Authored by: GaelicWizard on Oct 18, '06 10:51:13PM

There's still a bug, if anyone wants to get to it before me: (1) white space is NOT ignored, which can be confusing. The original script did not have this problem for white space at the end of the line, but did for white space at the beginning. My version keeps all white space, except for whitespace *after* the port number (end of the line).

Enjoy!

JP

---
Pell



[ Reply to This | # ]
(Rewrite) Another way to create quick-access SSH shortcuts
Authored by: Skurfer on Oct 19, '06 07:47:43AM

That might be useful for a larger audience, so thanks for the additions. In my particular case, I had my reasons for the way it was.

  1. I realize that the $access parameter seems misused in the stripped down version of the script I published. In my version of the script, the "type of access" is more than just a different username. It tells me "How do I get root access to this machine?" Some machines I access using ssh -l root, some using pbrun (PowerBroker), and some using pmrun (UPM).
  2. As for access under another username (or port), I think ~/.ssh/config is a more appropriate location for that. Specifying alternate settings in the .term file will only work if you open that .term file. By putting it in your ssh config, it will work with ssh from the command line and when you open a .term file. Of course, this doesn't account for situations where you have more than one (non-root) account on a machine. I should also mention that I have an account with the same name on almost every machine, so the usernames specified in ~/.ssh/config are rare (2 machines out of 45).
  3. I considered adding other metadata to the format of .hosts, but I wanted to keep it simple because its "real" purpose (or at least it's original purpose) was to enable tab completion on the command-line and I've had it in that format for years. And an even bigger factor in my decision to keep the format simple: I realized that most or all of the metadata I would have added is already available in an LDAP database we use in my office. Obviously, that won't be the case for most people.


[ Reply to This | # ]