Skip to content

Instantly share code, notes, and snippets.

@xtetsuji
Created January 15, 2018 04:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xtetsuji/72dae697d52f8fb657697f1f5eefa4bd to your computer and use it in GitHub Desktop.
Save xtetsuji/72dae697d52f8fb657697f1f5eefa4bd to your computer and use it in GitHub Desktop.
peco -> hostlist -> ssh, simple script. This script is beta quality because now I think this script is dirty.
#!/bin/bash
# phs - popup host ssh
# xtetsuji 2016/11/17
if [ "$1" ] && [ "_$1" = _-h -o "_$1" = _--help ] ; then
exec perldoc $0
fi
declare DEBUG
declare PHS_SCREEN_COMMAND PHS_TMUX_COMMAND PHS_OPEN_MODE PHS_SSH_COMMAND
declare ip_address_re='^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$'
# 独自ビルドなどでマルチプレクサコマンドが別の場所にある場合は環境変数で指定できる
screen_command=${PHS_SCREEN_COMMAND:-"screen -X screen"}
tmux_command=${PHS_TMUX_COMMAND:-tmux}
# open_mode の決定
open_mode=${PHS_OPEN_MODE:-}
if [ "$1" -a "${1:0:1}" = ":" ] ; then
open_mode="${1:1}"
shift
elif [ "$TERM" = "screen" ] ; then
open_mode="screen"
fi
# ssh コマンドをどのように発行するか決定
ssh_command=${PHS_SSH_COMMAND:-ssh}
if [ "$DEBUG" ] ; then
echo open_mode=$open_mode
echo ssh_command=$ssh_command
set -o xtrace
sleep 1
fi
function guess_ssh_execute_command {
local open_mode="$1"
local ssh_command="$2"
local host="$3"
local multip_command=
case "$open_mode" in
screen)
multip_command=$screen_command
;;
tmux)
multip_command=$tmux_command
;;
esac
# title
if [ "$open_mode" = screen ] && [ "$host" ] ; then
local short_host=${host/.*/}
if [[ $host =~ $ip_address_re ]] ; then
# これはIPアドレスなのでオクテット全部入れる
short_host=$host
fi
multip_command="$multip_command -t $short_host"
fi
local whole_command="$multip_command $ssh_command"
if [ "$DEBUG" ] ; then
whole_command="echo $whole_command"
fi
echo "$whole_command"
}
declare peco_arg="--initial-filter Regexp"
declare host_query="$1"
shift
if [ -z "$host_query" ] ; then
:
elif [ "${host_query:0:1}" = "+" ] ; then
peco_arg=""
host_query="${host_query:1}"
else
peco_arg="$peco_arg --query $host_query"
fi
if [ -n "$peco_arg" ] ; then
declare -a hostlist=( $(hostlist | peco $peco_arg) )
if [ $? != 0 ] ; then
echo "hostlist returns error code"
exit 1
fi
else
declare -a hostlist=($host_query)
fi
if [ ${#hostlist[@]} = 0 ] ; then
echo "hostlist incremental search is canceled."
exit
fi
declare host
for host in ${hostlist[@]} ; do
declare -a args=("$@")
declare whole_command=$(guess_ssh_execute_command "$open_mode" "$ssh_command" "$host")
if [ ${#args[@]} = 0 ] ; then
: "execute: $whole_command $host"
$whole_command $host
else
# replacement ${args[@]} by s/%h/$host/
declare i
for i in $( seq 0 $(( ${#args[@]} - 1 )) ) ; do
: i=$i
args[$i]=${args[$i]/\%h/$host}
done
: "execute: $whole_command" "${args[@]}"
$whole_command "${args[@]}"
fi
done
exit
: <<END_POD
=pod
=encoding utf-8
=head1 NAME
phs - popup host ssh
=head1 SYNOPSIS
# peco incremental only
phs
# peco incremental and execute
phs %h "wc -l /var/log/message"
phs user1@%h 'cat ~/.bashrc'
# open mode specify ^
phs ^screen
=head1 DESCRIPTION
phs は各ユーザが用意した hostlist コマンドの出力を peco で受け取り、
その選択結果に応じて1つもしくは複数のホストに対して SSH 接続を行うコマンドです。
=head1 ENVIRONMENT VARIABLES
=head2 DEBUG
DEBUG 変数に何か入っていると、デバッグモードで動作します。
デバッグモード時は実際にどういうコマンドが発行されるのかを表示し、
さらに実際の ssh コマンド自体は実行されません。
=head2 PHS_OPEN_MODE
オープンモードを指定します。現状 direct、screen、tmux のどれかを指定。
何も指定していない場合には $TERM 変数などから割り出し。
コマンドラインの第1引数で ^screen などと書くと上書きできます。
=head2 PHS_SSH_COMMAND
実際に SSH をするときのコマンドです。rsync の -e オプションと同様。
デフォルトは ssh ですが、これを ssh -vvv などとすることで詳細出力が可能となります。
さらに ssh -L 1234:localhost:1234 などといったオプション指定も可能。
=head2 PHS_SCREEN_COMMAND
オープンモードが screen の場合、SSH 接続のために新しいスクリーンを作成するためのコマンドを指定します。
デフォルトでは screen -X screen です。
=head2 PHS_TMUX_COMMAND
オープンモードが tmux の場合、SSH 接続のために新しい Tmux ウィンドウを作成するためのコマンドを指定します。
デフォルトでは tmux です。
xtetsuji が tmux を使っていないので、この設定は検証されていません。
=head1 SEE ALSO
hostlist, peco
=head1 AUTHOR
OGATA Tetsuji E<lt>tetsuji.ogata@gmail.comE<gt>
=cut
END_POD
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment