Это моя универсальная ssh
оболочка. Ни опция, ни адрес не прописаны. Единственное, что вам может понадобиться настроить - это путь к исполняемому файлу ssh
в строке 3 (вы можете использовать executable=ssh
, я выбрал полный путь). Вы найдете мой полный код ниже.
Допустим, вы сохранили его как sshmt
(«ssh, multi target»), куда указывает ваш $PATH
, и сделали его исполняемым с помощью chmod
. Затем ознакомьтесь с синтаксисом:
sshmt -h
Выдержка:
ИСПОЛЬЗОВАНИЕ
sshmt [-v] ARGS [+[N] ARGS]... [-- COMMON]
sshmt -h
СИНТАКСИС
Вызывает команду ssh
с первым набором аргументов ARGS
и общими аргументами COMMON
. Если эта команда возвращает состояние выхода 255
и существует второй набор аргументов ARGS
, то второй ssh
будет вызван с этими новыми ARGS
и COMMON
; потом третий и тд.
В вашем примере вы хотите вызвать его так:
sshmt 10.0.0.1 + my_machine.example.com + my_machine.example.com -J me@other_machine.example.com
или лучше с некоторыми удобными таймаутами:
sshmt 10.0.0.1 +2 my_machine.example.com +3 my_machine.example.com -J me@other_machine.example.com +5
Чтобы удаленно выполнить df -h
простым способом, вызовите:
sshmt 10.0.0.1 df -h +2 my_machine.example.com df -h +3 my_machine.example.com -J me@other_machine.example.com df -h +5
но вы не хотите повторяться, так что используйте вместо этого:
sshmt 10.0.0.1 +2 my_machine.example.com +3 my_machine.example.com -J me@other_machine.example.com +5 -- df -h
Трубы также должны работать:
echo 123 | sshmt 10.0.0.1 +2 my_machine.example.com +3 my_machine.example.com -J me@other_machine.example.com +5 -- sh -c "cat > /tmp/foo"
На практике вы можете определить псевдоним:
alias myssh='sshmt 10.0.0.1 +2 my_machine.example.com +3 my_machine.example.com -J me@other_machine.example.com +5 --'
затем войдите с
myssh
или выполнить команду как
myssh uptime
Это код. Вся его логика просто анализирует командную строку.
#!/usr/bin/env bash
executable=/usr/bin/ssh
exename="${executable##*/}"
myname="${0##*/}"
declare -a args
declare -a seq_opts
declare -a common_opts
main () {
split_opts "$@"
process_seq "${seq_opts[@]}" "+"
exit 255
}
split_opts () {
while [ $# -ne 0 ]; do
if [ "$1" = "--" ]; then
shift
common_opts=("$@")
break
else
seq_opts=("${seq_opts[@]}" "$1")
shift
fi
done
}
process_seq() {
if [ "$*" = "+" ] || [ "$1" = "-h" ]; then
print_help; exit 0
fi
while [ $# -ne 0 ]; do
if [ "${1:0:1}" != "+" ]; then
args=("${args[@]}" "$1")
else
timeout="${1:1}"
[[ "$timeout" =~ ^[0-9]*$ ]] || print_error
if [ "${#args[*]}" -ne 0 ]; then
printf '%s\n' "${myname}: trying ${args[*]}" >&2
"$executable" ${timeout:+-o ConnectTimeout=$timeout} "${args[@]}" "${common_opts[@]}"
status=$?
[ $status -ne 255 ] && exit $status
args=()
fi
fi
shift
done
}
print_error() {
cat >&2 << EOF
${myname}: error parsing command line
Try '$myname -h' for more information.
EOF
exit 254
}
print_help() {
cat << EOF
USAGE
$myname [-v] ARGS [+[N] ARGS]... [-- COMMON]
$myname -h
SYNOPSIS
Invokes \`${exename}' command with the first set of arguments ARGS
and common arguments COMMON. If this command returns
exit status of 255 and the second set of arguments ARGS
exists, then the second \`ssh' will be invoked with these
new ARGS and COMMON; then the third and so on.
Empty set of arguments is discarded without invoking \`ssh'.
Successful invocation of \`ssh' stops parsing the command
line and makes the script exit.
OPTIONS
-h print this help and exit (must be the first option)
+, +N execute \`ssh' with preceding ARGS and COMMON
N, if given, specifies timeout for \`ssh' invoked with
immediately preceding ARGS. This is just a convenient
alternative for \`-o ConnectTimeout=N'.
The final set of arguments may or may not have a terminating \`+'.
EXIT STATUS
The exit status is 254 in case of an error while parsing
the command line; 255, if none of \`${exename}' managed
to connect; or an exit status of successfully connected
\`${exename}' otherwise.
EXAMPLES
To try 10.0.0.1 and, if failed, the alternative address:
$myname 10.0.0.1 + my_machine.example.com
To execute \`df -h' with timeouts:
$myname 10.0.0.1 +3 my_machine.example.com +5 -- df -h
LICENCE
Creative Commons CC0.
EOF
}
main "$@"