我有以下脚本:传递变量到rsync的
#!/bin/sh
...
rsync -e 'ssh -i "$SSHKeyPath"'
的错误是:
Warning: Identity file $SSHKeyPath not accessible: No such file or directory.
我怎样才能$ SSHKeyGen的rsync之前评估被调用?
更新: fwiw,这是在OSX上。
我有以下脚本:传递变量到rsync的
#!/bin/sh
...
rsync -e 'ssh -i "$SSHKeyPath"'
的错误是:
Warning: Identity file $SSHKeyPath not accessible: No such file or directory.
我怎样才能$ SSHKeyGen的rsync之前评估被调用?
更新: fwiw,这是在OSX上。
有几种解决方案,我认为是比较容易:
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
您使用单引号,这是不能代替变量名与它的价值。这与双倍报价是一致的。
例如
$> path_to_file="/tmp/file"; rsync -e "$(ssh -i "$path_to_file")"
Warning: Identity file /tmp/file not accessible: No such file or directory.
我认为你的'$(...)'抛出了解决方案 - 它正在执行'ssh',而不是让'rsync'执行'ssh'。尝试用'echo hello'替换'rsync -e' - 即使它不应该被执行,你仍然会看到'ssh'的输出。 – sarnold
这个解决方案导致'usage:ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]' – eatloaf
看到我上面关于在测试中使用'echo(1)'的危险的有趣评论。呵呵。但是,仍然可以通过主机和路径完全尝试,并且我认为你会看到'ssh(1)'不能正常工作。 – sarnold
试试这个:
rsync -e "ssh -i ""$SSHKeyPath"
不幸的是,目标是脚本可移植。我认为使用这些方法需要在最终用户的机器上添加更多的代码。 – eatloaf
第二种解决方案对我来说很有意义,但是我在远程shell命令中得到了'丢失的尾部'。' – eatloaf
哦,我今晚学到了一个很好的教训:'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