2011-11-11 42 views
0

我有以下脚本:传递变量到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 
+0

不幸的是,目标是脚本可移植。我认为使用这些方法需要在最终用户的机器上添加更多的代码。 – eatloaf

+0

第二种解决方案对我来说很有意义,但是我在远程shell命令中得到了'丢失的尾部'。' – eatloaf

+0

哦,我今晚学到了一个很好的教训:'echo(1)'的输出并不总是值得信赖。它可能会像'ssh -i path''一样,但是当它通过'rsync(1)'传递给'execve(2)'时,它被解析成:'execve(“/ usr/bin/rsync”, [“rsync”,“-e”,“ssh”,“-i”,“/home/s...rsa'”,“/ tmp/...”...)'。显然,shell引用规则比我想起的更加微妙。用实际的'rsync(1)'测试让我得到一个实际的工作版本,如上所述。 – sarnold

0

您使用单引号,这是不能代替变量名与它的价值。这与双倍报价是一致的。

例如

$> path_to_file="/tmp/file"; rsync -e "$(ssh -i "$path_to_file")" 
Warning: Identity file /tmp/file not accessible: No such file or directory. 
+0

我认为你的'$(...)'抛出了解决方案 - 它正在执行'ssh',而不是让'rsync'执行'ssh'。尝试用'echo hello'替换'rsync -e' - 即使它不应该被执行,你仍然会看到'ssh'的输出。 – sarnold

+0

这个解决方案导致'usage:ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]' – eatloaf

+0

看到我上面关于在测试中使用'echo(1)'的危险的有趣评论。呵呵。但是,仍然可以通过主机和路径完全尝试,并且我认为你会看到'ssh(1)'不能正常工作。 – sarnold

0

试试这个:

rsync -e "ssh -i ""$SSHKeyPath"