2010年4月27日 星期二

An OpenBox PipeMenu

#!/bin/sh
####################################################################
# Generate a set of expect files to these defined servers ,        #
# Generate a OPENBox menu concludes those expect files.            #
# Auther: IceKimo                                                  #
# Date  : Aprill 27 2010                                           #
####################################################################

主要就是先產生一堆通往各主機的expect檔(這樣連線時節省輸入帳號密碼的時間,但是當然會有洩密問題啦~)再藉由這些expect檔產生出選單,就這麼簡單~

#Envirement Settings
EFF=$HOME/bin/.conn2 # ExecFileFolder
[ -d $EFF ] || ( rm -rf $EFF ; mkdir $EFF )
[ -x /usr/bin/gnome-terminal ] && TERMINAL="/usr/bin/gnome-terminal -x" || TERMINAL="/usr/bin/xterm -e"

基礎重要設定只有存放expect檔案的位置與連線程式,連線種類其實還可以更多去包含kermit的語言,不過,等2012吧~

#       Functions to create every expect files connect to server.
#       SSH and Telnet are different expect template.
#       The expect files can be edited after Generated.
create_expect() {
file_exp="$EFF/$3@$2.exp"
        echo "#!/usr/bin/expect" > $file_exp
        echo "set tiomeout 30" >> $file_exp
  if [ X${1:0:3} = "Xssh" ] ; then
# Depend on the password field , empty this by SSH PubkeyAuthentication
        if [ -n "$4" ] ; then
cat << EndOfSSHExpect >> $file_exp
        spawn $1 -l $3 $2
        expect "*assword:" {send "$4\r"}
EndOfSSHExpect

因為SSH連線可以使用鑰匙認證而不需要密碼,因此可以密碼留空白,其實這整個程式裡面大量使用HERE Document的轉向技巧產生各個檔案

        else
cat << EndOfSSHExpect2 >> $file_exp
        spawn $1 -l $3 $2
EndOfSSHExpect2
        fi
  else
# The TELNET PROTOCOL
cat << EndOfExpect >> $file_exp
spawn $1 $2
expect "ogin:"
send "$3\r"
expect "assword:"
send "$4\r"
EndOfExpect
  fi

希望可以個別放一些特殊expect語法的話,比如說登入後修改啥環境變數之類,把檔名寫好在$5欄

  if [-n "$5" ] ; then
        cat $5 >> $file_exp

  fi
  echo "interact" >> $file_exp
  chmod 510 $file_exp
}
# Configure file was embeded in this Script, Now I change it
# To edit config on a .config file, keep your password secret
ConfigFile=$EFF/.config

原本我是把設定值直接就跟程式寫在一起,不過這樣似乎太快樂了,還是拆出來一個檔好了

if [ !–x $ConfigFile ] ; then
cat << EndOfConfig > $ConfigFile
# Field up like the follow sample ; seperate by :
# PROTCOL:REMOTE_HOST:REMOTE_USER_ID:PASSWORD:OPITIONAL_EXPECT_FILE
telnet:ptt.cc:guest::
EndOfConfig
fi

echo "Choose an editor program you like to use, default is vi : " && read editor
which $editor
[ $?=0 ] && editor=`which $editor` || editor=`which vi`
$editor $ConfigFile

grep -v ^# $ConfigFile > $ConfigFile.tmp

exec 6< $ConfigFile.tmp
  OIFS=$IFS ; IFS=":"
while read pro host id passwd extfile <&6
do
        create_expect $pro $host $id $passwd $extfile
done

上面的作為是製造出設定檔,然後更改系統分隔字元,把設定檔餵進while read組合的迴圈,就會自動一行一行塞去做出expect檔案。exec <6 與<&6是指使用FD 6來作為串接的檔案代碼(File Descriptor),效果就是,嗯簡單的講,在UNIX觀念裡,所有東西都是檔案,FD 0通常就是標準輸入(鍵盤),所以這樣看FD 6就有如找個鍵盤來敲這檔案裡的字進程式。


  IFS=$OIFS ; unset OIFS ; rm $ConfigFile.tmp
###########Create the pipe menu for openbox ###############
pipe_menu=$HOME/.config/openbox/conn2.sh
echo '#/bin/sh' > $pipe_menu
cat << EndOfPipeMenu >> $pipe_menu
gen_menu() {
        # Generate Menu Item for Openbox
  echo "<item label=\""\$1"\">"
  echo -n '<action name="Execute"><execute>'
  echo $TERMINAL $EFF/\$1.exp
  echo "</execute></action>"
  echo "</item>"
}

這邊整段就沒啥,就是把PIPEMENU(另一支其實可以獨立的ShellScript)整個包起來用HERE Document產生出來後,最後作個提示如何修改openbox設定檔

echo '<openbox_pipe_menu>'
echo '<separator label="CONN2" />'

  echo "</item>"
}

echo '<openbox_pipe_menu>'
echo '<separator label="CONN2" />'
hosts=\$( ls $EFF/*.exp )
    for host in \$hosts
        do
          host=\$( basename \$host )
          host=\${host%.exp}
          gen_menu \$host
#         echo "<separator />"
        done
echo '</openbox_pipe_menu>'
EndOfPipeMenu
chmod +x $pipe_menu
cat << POST
Insert a line in your OPENBOX Menu $HOME/.config/openbox/menu.xml as example

<menu id="sshmenu" label="TERMINAL CONN2" execute="$HOME/.config/openbox/con
n.sh" />

POST

沒有留言: