Передача переменной в rsync

#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) by rsync(1) , оно было проанализировано в: execve("/usr/bin/rsync", ["rsync", "-e", "'ssh", "-i", "/home/s...rsa'", "/tmp/..." ...) . Очевидно, что правила цитирования в оболочке более тонкие, чем я помнил. Тестирование с использованием actual rsync(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"