From 34d2ef2ce899eb7c1bcb3cdd127d3ed606b78592 Mon Sep 17 00:00:00 2001 From: richardyu Date: Tue, 27 Sep 2016 22:33:06 +0800 Subject: [PATCH] #1 init repo, commit version 1.0 --- .go.conf.example | 4 ++ README.md | 88 ++++++++++++++++++++++++++++ go | 148 +++++++++++++++++++++++++++++++++++++++++++++++ ssh-expect | 34 +++++++++++ 4 files changed, 274 insertions(+) create mode 100644 .go.conf.example create mode 100644 README.md create mode 100755 go create mode 100755 ssh-expect diff --git a/.go.conf.example b/.go.conf.example new file mode 100644 index 0000000..7f590d8 --- /dev/null +++ b/.go.conf.example @@ -0,0 +1,4 @@ +# IP USER:PASS Label +192.168.1.7 user1:pass1 label:7 +192.168.1.8 user2:pass2 label:8 + diff --git a/README.md b/README.md new file mode 100644 index 0000000..36dd58d --- /dev/null +++ b/README.md @@ -0,0 +1,88 @@ +Go +== + +What is Go? +----------- + +This Go is not the programming language from Google. This is a shell command which can help manage multiple remote servers SSH access easily, and do not need to remember so many accounts for those servers. + +OS requirements +--------------- + +The command tested on MacOSX, but should be working on most linux distributions. It depends on expect on your local system, and the remote servers need to enable SSH. + +If you feels something wrong, please [file an issue](https://github.com/vipzhicheng/go/issues/new) on this project, because I do not test the scripts on every case, but I am happy to help you out. + +Usage +----- + +I am just showing the usage for MacOSX users, other OS usage maybe different, but the idea is same. + +### Check out code from Github + +``` +$ mkdir ~/bin +$ cd ~/bin +$ git clone https://github.com/vipzhicheng/go.git +$ cd go +$ cp .go.conf.example ~/.go.conf +$ chmod a+x go +$ chmod a+x ssh-expect +``` + +### Set PATH in .bash_profile + +``` +export PATH=~/bin/go:~/bin:$PATH +``` + +``` +$ source ~/.bash_profile +``` + +### Set ~/.go.conf, you can see demo settings as follows. + +``` +# IP USER:PASS LABEL + +192.168.1.7:22000 user1:pass1 label:7 +192.168.1.8 user2:pass2 label:8 +192.168.1.9 user3::absolute_private_file_path label:9 +``` + +You can ignore port setting if you are using default port(22) in remote server. + +### How to use this command + +``` +$ go label + +Found follow servers: (Which one do you want to connect?) +[1] user1@192.168.1.7 label:7 +[2] user2@192.168.1.8 label:8 +Please choose by ID: +1 + +Logging into user1@192.168.1.7 ... +spawn ssh user1@192.168.1.7 -p 22000 +user1@192.168.1.7's password: +Last login: Mon Mar 10 18:35:02 2014 from 192.168.1.6 +$ +``` + +### Options + +There is only one option, -g, with this option, you can add -D7070 to the connection. + +### Change log + +2015-06-01 +1. Ignore comments lines +2. Add support for secret file + +Inspiration & Thanks +-------------------- + +I know it must be somewhere about the situation of manage multiple SSH accesses via expect. Then I found [this](http://imbugs.com/blog/articles/99.html), which is written in Chinese. Thanks for the code, most of this project is from that code, but some features I need are missing. so I added them into this project. + + diff --git a/go b/go new file mode 100755 index 0000000..bfc5364 --- /dev/null +++ b/go @@ -0,0 +1,148 @@ +#!/bin/bash + +# Define config directory and config path +GO_HOME=~ +AUTHFILE=$GO_HOME/.go.conf + +# Parse options +while getopts gh ARGS +do + case $ARGS in + g) + extra_options="-D7070" + shift + ;; + h) + echo "usage: go [-gh] foo bar" + exit 0; + ;; + *) + echo "Unknow option: $ARGS" + echo "usage: go [-gh] foo bar" + exit 1; + ;; + esac +done + +# Config search function +# Support AND logic, separated by blank char +GREP() +{ + + if [ -z "$*" ]; then + var="^[^#].*" + tmp_var=`cat $AUTHFILE | grep -i $var` + echo "$tmp_var" + return + fi + + index=1; + for var in $@ + do + if [[ "$var" =~ ^- ]];then + index=$((index+1)); + continue + fi + + if [ "$var" = "${!index}" ];then + var="^[^#].*$var.*" + tmp_var=`grep -i $var $AUTHFILE` + else + var="^[^#].*$var.*" + tmp_var=`echo "$tmp_var" | grep -i $var` + fi + done + + echo "$tmp_var" +} + +# Get choice +GET_CHAR() +{ + read choice + echo $choice; +} + +# Support input keywords by arguments or read from command line input +if [ -z $1 ];then + echo -n "Please input the server IP or Label: " + read target +else + target=$@ +fi + +# Parse config search result +count=`GREP $target | wc -l` +targetfullname=`GREP $target | awk '{print $1}' | awk -F ':' '{print $1}'` +port=`GREP $target | awk '{print $1}' | awk -F ':' '{if ($2 > "") {print $2} else {print 22}}'` +passwd=`GREP $target | awk '{print $2}' | awk -F ':' '{if ($2 > "") {print $2} else {print "-"}}'` +sshkey=`GREP $target | awk '{print $2}' | awk -F ':' '{if ($3 > "") {print $3} else {print "-"}}'` +user=`GREP $target | awk '{print $2}' | awk -F ':' '{print $1}'` +label=`GREP $target | awk '{print $3}'` + +# Process the case of more than one items in search results. +if [ $count -gt 1 ];then + echo -e 'Found follow servers: (\033[0;31mWhich one do you want to connect?\033[0m)' + + arrtarget=($targetfullname) + arruser=($user) + arrpasswd=($passwd) + arrlabel=($label) + arrport=($port) + arrsshkey=($sshkey) + + length=${#arrtarget[@]} + + for ((i=0; i<$length; i++)) + do + echo -e '[\033[4;34m'$(($i+1))'\033[0m]' "${arruser[$i]}@${arrtarget[$i]}:${arrport[$i]} ${arrlabel[$i]}" + done + + # Choose one from search results + echo -n "Please choose by ID: " + choice=`GET_CHAR` + echo "" + + echo $choice; + + if [[ "$choice" =~ ^[0-9]+$ ]]; then + echo ''; + else + exit 1; + fi + + targetfullname=${arrtarget[$(($choice-1))]} + passwd=${arrpasswd[$(($choice-1))]} + user=${arruser[$(($choice-1))]} + label=${arrencoding[$(($choice-1))]} + port=${arrport[$(($choice-1))]} + sshkey=${arrsshkey[$(($choice-1))]} +fi + +# Bad cases +if [ -z $targetfullname ] || [ -z $user ];then + echo "No matching server~"; + exit 1; +fi +target=$targetfullname + +# Any key value should not be empty +if [ -z $port ]; then + port=22 +fi + +if [ -z $passwd ]; then + passwd=- +fi + +if [ -z $extra_options ]; then + extra_options=- +fi + +if [ -z $sshkey ]; then + sshkey=- +fi + +echo "Logging into ${user}@${target} ${label}..." + +ssh-expect $user $target $passwd $port $extra_options $sshkey diff --git a/ssh-expect b/ssh-expect new file mode 100755 index 0000000..eed388c --- /dev/null +++ b/ssh-expect @@ -0,0 +1,34 @@ +#!/usr/bin/expect +set USER [lindex $argv 0] +set TARGET [lindex $argv 1] +set PASSWD [lindex $argv 2] +set PORT [lindex $argv 3] +set OPTS [lindex $argv 4] +set SSHKEY [lindex $argv 5] + +trap { + set rows [stty rows] + set cols [stty columns] + stty rows $rows columns $cols < $spawn_out(slave,name) +} WINCH + +if { $OPTS == "-" } { + set OPTS "" +} + +if {$SSHKEY != "-"} { + spawn ssh $USER@$TARGET -p $PORT -i $SSHKEY $OPTS + expect { + "yes/no" { send "yes\r"; exp_continue } + } +} else { + spawn ssh $USER@$TARGET -p $PORT $OPTS + expect { + "yes/no" { send "yes\r"; exp_continue } + "password:" { send "$PASSWD\r" } + } +} + +interact { + timeout 60 { send " "} +}