【问题标题】:PHP - How to SCP local file from BASH OSX to remote via SSH with Password in PHP?PHP - 如何使用 PHP 中的密码通过 SSH 将本地文件从 BASH OSX SCP 发送到远程?
【发布时间】:2017-09-13 03:38:02
【问题描述】:

我希望 PHP 将 myfile.txt 发送到使用密码登录的远程 SSH。

从 OSX bash 我使用这个命令手动发送文件:

scp /Users/myname/Documents/myfile.txt root@192.168.1.116:/Docs/myfile.txt

因为我需要通过 PHP 来完成,所以我制作了这个 upload.sh bash 脚本:

#!/usr/bin/expect
spawn scp /Users/myname/Documents/myfile.txt root@192.168.1.116:/Docs/myfile.txt
expect "root@192.168.1.116's password:"
send "mYpassWORD\r"
interact

我可以在终端中使用:./update.sh 运行上面的代码,它会根据需要发送文件。

现在的问题是当我在 PHP 中添加这个 bash 脚本时,它不发送文件。

我试过了:

exec('/Library/WebServer/update.sh 2>&1', $output);
print_r($output); 

我被这个错误/消息卡住了:

Array
(
    [0] => spawn scp /Users/myname/Documents/myfile.txt root@192.168.1.116:/Docs/myfile.txt
    [1] => root@192.168.1.116's password:
)

在 bash 中发送密码并且一切正常,通过 PHP 它不会上传文件。 我还注意到我第一次通过 PHP 运行它时说 SSH 主机密钥不匹配,所以我将 .ssh 文件夹复制到服务器根位置并且该错误消失了。

任何人都可以请帮助如何使它工作? 谢谢

【问题讨论】:

  • 您是否尝试过生成一对 SSH 密钥并将您的公钥添加到服务器的 ~/.ssh/authorized_keys 文件中?这样就不需要输入密码,也不需要expect
  • @RuslanOsmanov 抱歉,不确定。当我通过终端登录时,它询问我是否要将其保存在 .ssh 中,我写了是。但是当使用 PHP 那么 Owner 是 WWW 意味着不同的帐户?我将 .ssh 文件夹复制到服务器,现在它不需要密钥。我还没有生成authorized_keys。我只有known_hosts。我怎样才能做到这一点?谢谢
  • 你不应该把你的私钥给任何人(!)。握手是通过公钥完成的。受信任的公钥应该注册在服务器的~/.ssh/authorized_keys 文件中,并且公钥应该保存在客户端的机器上。可以使用ssh-keygen 实用程序生成一对 SSH 密钥。例如,请参阅instructions on GitHub
  • @RuslanOsmanov 我在本地掩码和远程也生成了密钥。但遥控器仍然要求输入密码。从本地访问时,我应该使用远程公钥还是私钥?我都试过了,但没有运气。我试过了:ssh -i id_rsa.txt root@192.168.1.116
  • 在本地机器上生成一对密钥。将您的公钥放入$HOME/.ssh/authorized_keys,其中$HOMEroot 的主目录。检查 SSH 服务器配置 (/etc/ssh/sshd_config) 是否与您的设置匹配; AuthorizedKeysFile 选项尤为重要。您可以使用 SSH 客户端的 -v 选项进行调试,例如ssh -vvv root@...

标签: php bash macos ssh


【解决方案1】:

按预期工作,但不是坚如磐石的解决方案。

我找到了一个解决方案并让它工作,但不确定这是否是正确的方法。 问题与密码无关。问题是/曾经是:Bash 脚本太快了。还是 PHP 太快了?

无论如何,我通过在send "mYpassWORD\r" 之后添加sleep 解决了我的问题。 这是我的工作 Bash 命令,我从 PHP 访问它以使用密码将文件发送到远程:

#!/usr/bin/expect
spawn scp /Library/WebServer/Documents/test34/myfile.txt root@192.168.1.116:/Docs/myfile.txt
expect "root@192.168.1.116's password:"
send "mYpassWORD\r"
sleep 0.2
interact

我把它保存为:update.sh 并做了chmod +x update.sh

然后在 PHP 文件中:index.php 我写道:

<?php
$do = shell_exec("(/Library/WebServer/Documents/test34/update.sh)");
var_dump($do);
?>

得到了这个SUCCESS结果

string(320) "spawn scp /Library/WebServer/Documents/test34/myfile.txt root@192.168.1.116:/Docs/myfile.txt
root@192.168.1.116's password: 

myfile.txt                                  0%    0     0.0KB/s   --:-- ETA
myfile.txt                                100% 3649     3.6KB/s   00:00    
"

所以只需在 Bash 脚本中添加 sleep 0.2即可解决问题。

我也尝试过sleep 0.1,但后来出现错误。因此睡眠时间可能取决于您的文件有多大? myfile.txt 只有 3.6kb 和 0.2 秒的睡眠效果很好。

如果您的文件更大,您可以尝试sleep 1sleep 5 等。

此方法有效并解决了问题,但感觉不安全,因为如果每次调用的文件大小不同或 ssh 连接缓慢,它可能会失败。

如果有人可以为改进此答案做出贡献,我将不胜感激。

【讨论】:

    猜你喜欢
    • 2013-02-16
    • 2019-07-21
    • 2012-10-27
    • 2012-07-03
    • 2015-12-25
    • 1970-01-01
    • 2010-12-03
    • 2015-01-29
    • 2012-08-03
    相关资源
    最近更新 更多