
Я пишу bash-скрипт на Raspberry Pi OS (на основе Debian 12 Bookworm). Скрипт пытается сделать что-то вроде
ssh "$args" "$user"@"$ip" 'command'
Из того, что я читал, это стандартная практика. Однако я обнаружил, что когда $args
содержит более одного аргумента, например
-v -i /path/to/keyfile -o StrictHostKeyChecking=yes
и затем выполнение
ssh "$args" "$user"@"$ip" 'echo "Success in logging into $HOSTNAME"'
ssh возвращает следующее со статусом выхода 255
:
unknown option --
usage: ssh [-46AaCfGgKkMNnqsTtVvXxYy] [-B bind_interface]
[-b bind_address] [-c cipher_spec] [-D [bind_address:]port]
[-E log_file] [-e escape_char] [-F configfile] [-I pkcs11]
[-i identity_file] [-J [user@]host[:port]] [-L address]
[-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]
[-Q query_option] [-R address] [-S ctl_path] [-W host:port]
[-w local_tun[:remote_tun]] destination [command [argument ...]]
Однако выполнение той же команды с использованием только содержимого $args
вместо использования $args
завершается успешно и завершается со статусом 0
:
ssh -v -i /path/to/keyfile -o StrictHostKeyChecking=yes "$user"@"$ip" 'echo "Success in logging into $HOSTNAME"'
Иными словами, использование $args
прекрасно работает, когда есть только один аргумент, например:
-o StrictHostKeyChecking=yes
Что здесь происходит? Что я могу сделать, чтобы предотвратить это? Из этого unknown option --
может показаться, что что-то разбирает $args
и удаляет некоторые вещи из него, потому что он жалуется на это только тогда, когда есть два или более аргументов (два вхождения -
in $args
)?
решение1
(Вероятно, мне следует закрыть это как дубликат, но давайте все равно попробуем объяснить конкретный случай.)
Указанное расширение "$args"
производитодинаргумент, поэтому по сути вы запускаете ssh "-v -i /path/to/keyfile -o StrictHostKeyChecking=yes" ...
. Пробелы и тире там воспринимаются как символы опций, аналогично тому, как работают сложенные опции в более полезных случаях, таких как -abc
. Тире не является допустимой опцией, поэтому вы получаете жалобу.
Если ssh "$args"
кажется, что работает с args='-o StrictHostKeyChecking=yes'
, это, вероятно, потому, что парсер для -o
игнорирует пробелы (аналогично тому, как ssh_config
игнорируются пробелы в ). Попробуйте то же самое с args='-i /path/to/keyfile'
, и вы, скорее всего, получите ошибку «файл не найден», так как вы просто включили начальный пробел в имя файла. ( args='-i/path/to/keyfile'
без пробела, конечно, сработало бы.)
Видеть: