Compare commits

...

3 Commits

Author SHA1 Message Date
70614af310 feat(riot): print help when no argument or no remote 2025-06-21 05:39:39 +08:00
4e99cc1580 feat(riot): sshd can specify the local port 2025-06-21 05:09:29 +08:00
3bdc43421d feat(riot): refactor argparse
feat(riot): add `--password` and `--`

feat(common.sh): argparse supports `--`

feat(riot): refactor ping to ping remote
2025-06-21 04:57:26 +08:00
3 changed files with 134 additions and 87 deletions

View File

@ -4,7 +4,7 @@ THIS_DIR=$( cd "$( dirname "${BASH_SOURCE[0]:-${(%):-%x}}" )" && pwd )
source "$THIS_DIR/../tools/common.sh" source "$THIS_DIR/../tools/common.sh"
RIOT_TRUST_CLIENT=${RIOT_TRUST_CLIENT:-${DFS_TRUST:-0}} RIOT_TRUST_CLIENT=${RIOT_TRUST_CLIENT:-${DFS_TRUST:-0}}
RIOT_TRUST_SERVER=${RIOT_TRUST_SERVER:-0} RIOT_TRUST_SERVER=${RIOT_TRUST_SERVER:-0}
RIOT_EXTRA_OPTIONS="" EXTRA_SSH_OPTIONS=()
# config # config
RIOT_CONFIG_FILES=( RIOT_CONFIG_FILES=(
@ -83,12 +83,12 @@ parse_remote() {
TRUST_SERVER=1 TRUST_SERVER=1
PORT="" # optional PORT="" # optional
USERNAME="" # optional USERNAME="" # optional
SSH_OPTIONS="-o RequestTTY=yes" # optional SSH_OPTIONS=("-o" "RequestTTY=yes")
if [[ "$RIOT_TRUST_CLIENT" == "1" ]]; then if [[ "$RIOT_TRUST_CLIENT" == "1" ]]; then
SSH_OPTIONS="$SSH_OPTIONS -o PermitLocalCommand=yes" SSH_OPTIONS+=("-o" "PermitLocalCommand=yes")
if [[ "$(get_os_type)" != "msys" ]]; then if [[ "$(get_os_type)" != "msys" ]]; then
test "$DFS_DRY_RUN" = "1" || mkdir -p ~/.ssh/master-socket test "$DFS_DRY_RUN" = "1" || mkdir -p ~/.ssh/master-socket
SSH_OPTIONS="$SSH_OPTIONS -o ControlMaster=auto -o ControlPath=~/.ssh/master-socket/%C" SSH_OPTIONS+=("-o" "ControlMaster=auto" "-o" "ControlPath=~/.ssh/master-socket/%C")
fi fi
fi fi
# handle input # handle input
@ -115,31 +115,30 @@ parse_remote() {
done done
# construct cmd # construct cmd
if [[ "$RIOT_TRUST_SERVER" == "1" || "$TRUST_SERVER" == "1" ]]; then if [[ "$RIOT_TRUST_SERVER" == "1" || "$TRUST_SERVER" == "1" ]]; then
SSH_OPTIONS="$SSH_OPTIONS -o ForwardX11=yes -o ForwardAgent=yes" SSH_OPTIONS+=("-o" "ForwardX11=yes" "-o" "ForwardAgent=yes")
fi fi
if [[ -n "$jump_servers" ]]; then if [[ -n "$jump_servers" ]]; then
SSH_OPTIONS="$SSH_OPTIONS -o ProxyJump=$jump_servers" SSH_OPTIONS+=("-o" "ProxyJump=$jump_servers")
fi fi
} }
eval_or_echo() { eval_or_echo() {
local cmd="$@"
local DO="" local DO=""
local tmux_win=0
if [[ "$DFS_DRY_RUN" == "1" ]]; then if [[ "$DFS_DRY_RUN" == "1" ]]; then
DO=echo DO=echo
fi fi
if [[ "$RIOT_USE_TMUX" == "1" ]]; then if [[ "$USE_TMUX" == "1" ]]; then
if [[ -z "$RIOT_TMUX_SESS" ]]; then if [[ -z "$TMUX_SESS" ]]; then
RIOT_TMUX_SESS=riot-$(date +%s) TMUX_SESS=riot-$(date +%s)
RIOT_TMUX_WIN=0 $DO tmux new-session -d -s $TMUX_SESS bash -l
$DO tmux new-session -d -s $RIOT_TMUX_SESS bash -l
else else
RIOT_TMUX_WIN=$((RIOT_TMUX_WIN+1)) tmux_win=$((tmux_win+1))
$DO tmux new-window -t $RIOT_TMUX_SESS:$RIOT_TMUX_WIN -d bash -l $DO tmux new-window -t $TMUX_SESS:$tmux_win -d bash -l
fi fi
$DO tmux send-keys -t $RIOT_TMUX_SESS:$RIOT_TMUX_WIN "$cmd" Enter $DO tmux send-keys -t $TMUX_SESS:$tmux_win "${CMD[@]}" Enter
else else
$DO $cmd $DO "${CMD[@]}"
fi fi
} }
@ -151,15 +150,25 @@ prepare_ssh_cmd() {
else else
local port_param='-p' local port_param='-p'
fi fi
echo "$ssh_bin ${PORT:+$port_param} $PORT $SSH_OPTIONS $RIOT_EXTRA_OPTIONS $SCP_SRC $USERNAME${USERNAME:+@}$SERVER $SCP_DST ${@:2}" CMD=(
"$ssh_bin"
"${PORT:+$port_param}" "$PORT"
"${SSH_OPTIONS[@]}"
"${EXTRA_SSH_OPTIONS[@]}"
"$SCP_SRC"
"$USERNAME${USERNAME:+@}$SERVER"
"$SCP_DST"
"${@:2}"
)
for i in ${!CMD[@]}; do if [[ -z "${CMD[i]}" ]]; then unset CMD[i]; fi; done
} }
# ssh # ssh
run_ssh() run_ssh()
{ {
local cmd="$(prepare_ssh_cmd $@)" prepare_ssh_cmd "$@"
fmt_note "-->" $cmd fmt_note "-->" "${CMD[@]}"
eval_or_echo $cmd eval_or_echo
} }
# sshl # sshl
@ -171,24 +180,22 @@ run_sshl()
arg=localhost:$arg arg=localhost:$arg
fi fi
local port=$(get_free_port) local port=$(get_free_port)
SSH_OPTIONS+=("-NC" "-L" "$port:$arg")
SSH_OPTIONS="$SSH_OPTIONS -NC -L $port:$arg" prepare_ssh_cmd ssh
local cmd="$(prepare_ssh_cmd ssh)" fmt_note "-->" "${CMD[@]}"
fmt_note "-->" $cmd
fmt_note " > please access localhost:$port" fmt_note " > please access localhost:$port"
eval_or_echo $cmd eval_or_echo
} }
# sshd # sshd
run_sshd() run_sshd()
{ {
local port=$(get_free_port) local port=${1:-$(get_free_port)}
SSH_OPTIONS+=("-NC" "-D" "$port")
SSH_OPTIONS="$SSH_OPTIONS -NC -D $port" prepare_ssh_cmd ssh
local cmd="$(prepare_ssh_cmd ssh)" fmt_note "-->" "${CMD[@]}"
fmt_note "-->" $cmd
fmt_note " > please access localhost:$port" fmt_note " > please access localhost:$port"
eval_or_echo $cmd eval_or_echo
} }
# scp # scp
@ -208,15 +215,27 @@ run_scp() {
SERVER="$SERVER":"$src" SERVER="$SERVER":"$src"
SCP_DST="$dst" SCP_DST="$dst"
fi fi
SSH_OPTIONS="$SSH_OPTIONS -r" SSH_OPTIONS+=("-r")
local cmd="$(prepare_ssh_cmd scp)" prepare_ssh_cmd scp
fmt_note "-->" $cmd fmt_note "-->" "${CMD[@]}"
eval_or_echo $cmd eval_or_echo
}
# ping
run_ping() {
CMD=(ping)
if [[ "$1" == "ping4" ]]; then
CMD+=(-4)
elif [[ "$1" == "ping6" ]]; then
CMD+=(-6)
fi
CMD+=(-c 4 "$SERVER")
fmt_note "-->" "${CMD[@]}"
eval_or_echo
} }
# remove host keys # remove host keys
remove_hostkey() remove_hostkey() {
{
local key local key
if [[ -z "$PORT" || "$PORT" == "22" ]]; then if [[ -z "$PORT" || "$PORT" == "22" ]]; then
key=$SERVER key=$SERVER
@ -229,94 +248,118 @@ remove_hostkey()
# main # main
print_help() print_help()
{ {
fmt_info "usage: $0 <service> [command] [options]" fmt_info "usage: $0 [-Ddhlqt] [--dry-run] [--dev] [--help] [--lite] [--quite] [--trust] [--tmux] [--password] [[-o ssh-option]...] remote [command] [--] [ssh-command-args]"
cat <<EOF cat <<EOF
available commands: available commands:
- ssh (default) - ssh [ssh-command-args] (default)
- tmux (run ssh in multiple tmux windows) - tmux [ssh-command-args] (run ssh in multiple tmux windows)
- sshl (ssh -L) - sshl [local-port:remote-host:]remote-port (ssh -L)
- sshd (ssh -D) - sshd [local-port] (ssh -D)
- zssh - zssh [ssh-command-args]
- sftp - sftp
- scp source destination
- rm (remove host keys) - rm (remove host keys)
- ping/ping6 (let the remote to ping the given target) - ping/ping4/ping6 (ping the remote servers)
EOF EOF
} }
router() { router() {
if [[ -z "$1" || "$1" == "-h" || "$1" == "--help" ]]; then local positional=()
while [[ $# > 0 ]]; do
case "$1" in
-h|--help )
print_help print_help
exit exit 0
fi ;;
-t|--trust )
while [[ "$1" == -* ]]; do
if [[ "$1" == "--tmux" ]]; then
RIOT_USE_TMUX=1
shift
continue
elif [[ "$1" == "-t" || "$1" == "--trust" ]]; then
RIOT_TRUST_SERVER=1 RIOT_TRUST_SERVER=1
;;
--tmux )
USE_TMUX=1
;;
--password )
EXTRA_SSH_OPTIONS+=("-o" "PasswordAuthentication=yes" "-o" "PubkeyAuthentication=no")
;;
-o )
EXTRA_SSH_OPTIONS+=("-o" "$2")
shift shift
continue ;;
fi -- )
RIOT_EXTRA_OPTIONS="$RIOT_EXTRA_OPTIONS $1"
if [[ "$1" == "-o" ]]; then
RIOT_EXTRA_OPTIONS="$RIOT_EXTRA_OPTIONS $2"
shift shift
fi positional+=("$@")
break
;;
-* )
fmt_fatal "unknown option: $1"
;;
* )
positional+=("$1")
;;
esac
shift shift
done done
IFS=',' read -ra remotes <<< "${positional[0]}"
IFS=',' read -ra remotes <<< "$1" for i in ${!remotes[@]}; do if [[ -z "${remotes[i]}" ]]; then unset remotes[i]; fi; done
for ((i=0; i<${#remotes[@]}; i++)); do if [[ "${#positional[@]}" == "0" || "${#remotes[@]}" == "0" ]]; then
remote="${remotes[i]}" print_help
if [[ -z "$remote" ]]; then exit 1
continue
fi fi
for i in ${!remotes[@]}; do
remote="${remotes[i]}"
local batch_func="${remote}.batch" local batch_func="${remote}.batch"
if is_function "$batch_func"; then if is_function "$batch_func"; then
"$batch_func" "$batch_func"
continue continue
fi fi
parse_remote "$remote" parse_remote "$remote"
case $2 in case "${positional[1]}" in
ssh|tmux|"" ) ssh|tmux|"" )
[[ "$2" == tmux ]] && RIOT_USE_TMUX=1 [[ "${positional[1]}" == tmux ]] && USE_TMUX=1
run_ssh ssh "${@:3}" run_ssh ssh "${positional[@]:2}"
;; ;;
ping|ping6 ) ping|ping4|ping6 )
run_ssh ssh "${@:2}" test "${#positional[@]}" -eq 2 || fmt_fatal "ping requires no arguments"
run_ping "${positional[1]}"
;; ;;
zssh ) zssh )
run_ssh zssh run_ssh zssh "${positional[@]:2}"
;; ;;
sftp ) sftp )
run_ssh sftp run_ssh sftp "${positional[@]:2}"
;; ;;
sshl ) sshl )
test -n "$3" || fmt_fatal "no target address provided" test -n "${positional[2]}" || fmt_fatal "no target address provided"
run_sshl "$3" test "${#positional[@]}" -eq 3 || fmt_fatal "sshl requires exactly one argument"
run_sshl "${positional[2]}"
;; ;;
sshd ) sshd )
test "${#positional[@]}" -le 3 || fmt_fatal "sshd requires one or no arguments"
if [[ "${#positional[@]}" -eq 3 ]]; then
check_port "${positional[2]}" || fmt_fatal "invalid port number: ${positional[2]}"
run_sshd "${positional[2]}"
else
run_sshd run_sshd
fi
;; ;;
scp ) scp )
test -n "$3" || fmt_fatal "no source path specified" test "${#positional[@]}" -eq 4 || fmt_fatal "scp requires exactly two arguments: source and destination"
test -n "$4" || fmt_fatal "no destination path specified" test -n "${positional[2]}" || fmt_fatal "no source path specified"
run_scp "$3" "$4" test -n "${positional[3]}" || fmt_fatal "no destination path specified"
run_scp "${positional[2]}" "${positional[3]}"
;; ;;
rm ) rm )
test "${#positional[@]}" -eq 2 || fmt_fatal "rm requires no arguments"
remove_hostkey remove_hostkey
;; ;;
* ) * )
print_help print_help
fmt_fatal "unknown command: $2" fmt_fatal "unknown command: ${positional[1]}"
;; ;;
esac esac
done done
if [[ -n "$RIOT_TMUX_SESS" ]]; then if [[ -n "$TMUX_SESS" && "$DFS_DRY_RUN" != "1" ]]; then
tmux attach-session -t $RIOT_TMUX_SESS tmux attach-session -t $TMUX_SESS
fi fi
} }

View File

@ -13,7 +13,10 @@ if [[ "${BASH_SOURCE[0]}" != "${0}" ]]; then
ARG="" ARG=""
GOT_OPTS=() GOT_OPTS=()
while [[ $# > 0 || -n "$ARG" ]]; do while [[ $# > 0 || -n "$ARG" ]]; do
if [[ -z "$ARG" ]]; then ARG=$1; shift; fi if [[ -z "$ARG" ]]; then
if [[ "$1" == "--" ]]; then GOT_OPTS+=("$@"); break; fi
ARG="$1"; shift;
fi
case $ARG in case $ARG in
-q*|--quite ) export DFS_QUIET=1 ;; -q*|--quite ) export DFS_QUIET=1 ;;
-l*|--lite ) export DFS_LITE=1 ;; -l*|--lite ) export DFS_LITE=1 ;;

View File

@ -42,6 +42,7 @@ test $(echo | tools/common.sh ask_for_Yn "test") = "1"
test $(DFS_QUIET=1 tools/common.sh ask_for_Yn "test") = "1" test $(DFS_QUIET=1 tools/common.sh ask_for_Yn "test") = "1"
test "$(DFS_TRUST=1 riot time@is.impt:2222/yes@you-r.right/you@are.really.recht./ibd./try@it,another@host scp /tmp/ ./tmp -D 2>/dev/null)" = 'scp -P 12022 -o RequestTTY=yes -o PermitLocalCommand=yes -o ControlMaster=auto -o ControlPath=~/.ssh/master-socket/%C -o ProxyJump=time@is.impt:2222,yes@you-r.right:12022,you@are.really.recht:12022,root@ibd:12022 -r try@it.dxng.net:/tmp/ ./tmp test "$(DFS_TRUST=1 riot time@is.impt:2222/yes@you-r.right/you@are.really.recht./ibd./try@it,another@host scp /tmp/ ./tmp -D 2>/dev/null)" = 'scp -P 12022 -o RequestTTY=yes -o PermitLocalCommand=yes -o ControlMaster=auto -o ControlPath=~/.ssh/master-socket/%C -o ProxyJump=time@is.impt:2222,yes@you-r.right:12022,you@are.really.recht:12022,root@ibd:12022 -r try@it.dxng.net:/tmp/ ./tmp
scp -P 12022 -o RequestTTY=yes -o PermitLocalCommand=yes -o ControlMaster=auto -o ControlPath=~/.ssh/master-socket/%C -o ForwardX11=yes -o ForwardAgent=yes -r another@host.dxng.net:/tmp/ ./tmp' scp -P 12022 -o RequestTTY=yes -o PermitLocalCommand=yes -o ControlMaster=auto -o ControlPath=~/.ssh/master-socket/%C -o ForwardX11=yes -o ForwardAgent=yes -r another@host.dxng.net:/tmp/ ./tmp'
test "$(riot you@example.com:55 -tD ssh --password -- ping -c 1 2>/dev/null)" = 'ssh -p 55 -o RequestTTY=yes -o PermitLocalCommand=yes -o ControlMaster=auto -o ControlPath=~/.ssh/master-socket/%C -o ForwardX11=yes -o ForwardAgent=yes -o PasswordAuthentication=yes -o PubkeyAuthentication=no you@example.com ping -c 1'
# check alias # check alias
alias p114 alias p114