#bash #rsync
#bash #rsync
Вопрос:
У меня есть следующий скрипт:
#!/bin/sh
...
rsync -e 'ssh -i "$SSHKeyPath"'
Ошибка заключается в:
Warning: Identity file $SSHKeyPath not accessible: No such file or directory.
Как я могу вычислить $ SSHKeyGen перед вызовом rsync?
ОБНОВЛЕНИЕ: fwiw, это в OSX.
Ответ №1:
Есть несколько решений, которые, на мой взгляд, проще:
- Используйте
ssh-agent(1)
, чтобы разблокировать закрытую часть ключа дляssh(1)
процессов по мере необходимости. Это, безусловно, самый простой механизм в использовании. -
Используйте
~/.ssh/config
для выбора другого закрытого ключа на основе имени хоста:host backuphost IdentityFile ~/.ssh/different_key
Тогда нет необходимости указывать ключ в командной строке.
Обновить
Учитывая, что вы пытаетесь отделить ключ от отдельного пользователя, теперь это имеет для меня гораздо больше смысла. Если вы используете другую переменную в sh
, вы можете заставить работать ваш оригинальный подход:
$ cat foo.sh
#!/bin/sh
SSHKeyPath=/home/sarnold/.ssh/id_rsa
KEYARG="ssh -i $SSHKeyPath"
rsync -e "$KEYARG" /tmp/pointless localhost:/tmp/new_pointless
$ ./foo.sh
Enter passphrase for key '/home/sarnold/.ssh/id_rsa':
skipping directory pointless
Комментарии:
1. К сожалению, цель состоит в том, чтобы скрипт был переносимым. Я думаю, что для использования этих методов потребуется больше кода на компьютере конечного пользователя.
2. Второе решение имеет смысл для меня, но я получаю
Missing trailing-' in remote-shell command.
3. О боже, сегодня вечером я извлек хороший урок: выводам из
echo(1)
не всегда можно доверять. Это могло бы выглядеть как'ssh -i path'
, но когда оно было переданоexecve(2)
byrsync(1)
, оно было проанализировано в:execve("/usr/bin/rsync", ["rsync", "-e", "'ssh", "-i", "/home/s...rsa'", "/tmp/..." ...)
. Очевидно, что правила цитирования в оболочке более тонкие, чем я помнил. Тестирование с использованием actualrsync(1)
позвольте мне получить фактическую рабочую версию, приведенную выше.
Ответ №2:
Вы используете одинарные кавычки, которые не могут заменить имя переменной ее значением. С двойными кавычками все будет в порядке.
Например
$> path_to_file="/tmp/file"; rsync -e "$( ssh -i "$path_to_file" )"
Warning: Identity file /tmp/file not accessible: No such file or directory.
Комментарии:
1. Я думаю, что ваше
$( ... )
отбрасывает решение — оно выполняетсяssh
прямо тогда и там, вместо того, чтобы позволитьrsync
выполнитьssh
. Попробуйте заменитьrsync -e
наecho hello
— вы все равно увидите вывод изssh
, даже если он еще не должен быть выполнен.2. Это решение приводит к
usage: ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]
3. Смотрите мои забавные комментарии выше об опасностях использования
echo(1)
в тестировании. Хе-хе. Но все же, попробуйте это полностью с хостами и путями, и я думаю, вы увидите, чтоssh(1)
работает неправильно.
Ответ №3:
Попробуйте это:
rsync -e "ssh -i ""$SSHKeyPath"