Будет проще, если вы установите отдельные флаги для каждой активированной опции, чтобы вам не приходилось анализировать еще одну строку, чтобы проверить, использовалась ли опция.
Например:
#!/bin/bash
self=$0
show_help () {
cat <<END_HELP
Usage: $self [-r] [-l|-u] pathname [...]
Options:
info about options here
END_HELP
}
recurse=0 # don't recurse by default
lowercase=1 # lowercase by default
while getopts rluh opt; do
case $opt in
r) recurse=1 ;;
l) lowercase=1 ;;
u) lowercase=0 ;;
h) show_help
exit ;;
*) echo 'Error in parsing options' >&2
exit 1
esac
done
shift "$(( OPTIND - 1 ))"
for pathname do
if [ -d "$pathname" ] && [ "$recurse" -eq 1 ]; then
# recurse here
fi
if [ "$lowercase" -eq 1 ]; then
# turn into lowercase
else
# turn into uppercase
fi
done
Обратите внимание, что код после shift
является просто примером кода. Я бы посоветовал вам вместо цикла использовать find
для выполнения рекурсии (, возможно, во всех случаях, даже если флаг recursion
не установлен ).
Между прочим, shift
избавляется от всех проанализированных опций из "$@"
, так что в списке позиционных параметров остаются только операнды пути. Это то, что цикл впоследствии повторяет.
Код, как написано выше, использует разумные значения по умолчанию (они должны быть упомянуты в тексте справки ). Это означает, что вполне нормально запускать скрипт без каких-либо опций. В качестве примечания, запуск инструмента с без аргументов, вероятно, не должен приводить к ошибке. Работы нет, поэтому не надо делать никакой работы.
Обычно я использую ProxyCommand, как упоминал muru.
Кроме того, почему бы вам не использовать ключ вместо пароля для аутентификации? { когда я начинаю использовать Linux, я всегда использую пароль, но однажды введя ключ, вы просто не вернетесь }
Я могу поместить это в свой конфигурационный файл ssh и напрямую подключиться к серверу по ssh с помощьюssh server
:
Host server
ControlMaster auto
ProxyCommand ssh -W %h:%p -i your_key_for_Jump user@jump
IdentityFile your_key_for_server_if_not_idrsa
User ssh_user_for_server
sshpass можно использовать для передачи двух паролей. Необходимо использовать два разных источника паролей(-e
и -d
), причем один из источников используется в каждом из двух вызовов sshpass.
env SSHPASS="JUMP_PASSWORD" \
sshpass -d 123 ssh \
-o ProxyCommand="sshpass -e ssh -W %h:%p JUMP_USER@JUMP_HOST" \
TARGET_USER@TARGET_HOST \
123<<<TARGET_PASSWORD
В приведенном выше примере кода узел перехода будет использовать ПАРОЛЬ ПЕРЕХОДА _, указанный для sshpass (-e
), а целевой узел будет использовать ЦЕЛЕВОЙ ПАРОЛЬ _, указанный для sshpass (-d
).
Можно также указать пароль с помощью sshpass (-p
), но это небезопасно, поскольку пароль будет отображаться в списке процессов (ps ). В приведенном выше примере используется sshpass, так что ни один пароль не отображается в списке системных процессов.
Источник пароля переменной среды (sshpass -e )должен использоваться с ProxyCommand для узла перехода. Переменная среды считывается с помощью sshpass в вызове «-o ProxyCommand», но при использовании источника дескриптора файла (sshpass -d )пароль должен быть предоставлен в значении ProxyCommand в кавычках и, таким образом, может можно увидеть в выводе списка процессов. (напр.-o ProxyCommand="sshpass -d 124 ssh -W %h:%p JUMP_USER@JUMP_HOST 124<<<JUMP_PASSWORD"
)< -так что это неблагоприятно.
Примечание. :Когда я использую этот метод, sshpass
НЕ устанавливается на JUMP _HOST.
Обновление Это решение также можно использовать с rsync
.env SSHPASS="JUMP_PASSWORD" \
rsync -v -a \
-e "sshpass -d 123 ssh \
-o ProxyCommand=\"sshpass -e ssh -W %h:%p USER@JUMP_HOST\" USER@TARGET_HOST" \
:/remote/directory/ /local/directory/ \
123<<<TARGET_PASSWORD
См. мой ответ на SuperUser:https://superuser.com/questions/1646074/why-rsync-with-jump-host-and-sshpass-not-working/1689136#1689136