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


Click here to return to the '(Rewrite) 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.
(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 | # ]