uncategorized

php中调用外部命令, 用户权限问题

今天有个新需求, 将一个很大的文件(超过1G)存放到亚马逊的S3存储上面, 文件是通过网页
post给php的, 天啦, 这怎么可能, php的执行的时候是有执行时间和post的body体大小都是
有限制的. 所以无法通过直接发送一个post请求来完成文件的上传工作. 这时想到wget -c
可以实现文件的断点续传工作.研究一下是什么个情况.

http的头定义

可以简单看一下http的头定义

重点看一下, 当使用http协议请求时, 返回的状态码是206时的情况(续传原理的关键)

找了一些资料了, 知道了点http的断点续传是咋回事, 之后老大给我了一个jquery的插件(
Real Ajax Uploader
), 哈哈, 看了一下帮助文档, 在本地把一个很大的文件上传服务
器的问题就解决了, 我的服务器和S3都在北京, Aws内部的传输速度是很快的, 只要文件在e
c2上面, 然后把文件上传至S3上面秒秒钟的事了.(没有直接从本地用类似Cyderduck的工具的
直接上传S3是有原因的, 这里通过ec2中转不是多此一举).

当我们的文件在ec2上面时, 平时的时候我是用Aws提供的CLI接口aws s3来处理S3上存储
的文件的, 因为我们的文件是用php脚本post接收的, 当然在php脚本中我们可以调用外部的
命令行aws s3接口来实现我们的文件从ec2到S3, 当我在php脚本里面执行类似于这样的一
个函数调用时:

1
exec("aws s3 cp local.txt s3://bucket/remote.txt");

S3一直接不到文件, 我在本地直接执行aws s3 cp local.txt s3://bucket/remote.txt),
发现是可以把文件上传到S3上面的, 然后我把这条命令的返回在php里面打印出来

1
Unable to locate credentials. You can configure credentials by running "aws configure".

这个是什么原因的了, 想不清楚, 我明明在ec2-user这个用户的家目录下配置了环境的(这
里强调一下我是在ec2-user这个用户下配置的, 这个就是原因了), 想不到原因, 然后我用
了另外一个S3的命令行工具, s3cmd

1
exec("s3cmd put local.txt s3://bucket/remote.txt");

哈哈, 这次的错误提示就比较友好了, 仔细想想, 我找到问题的原因了

1
2
3
ERROR: /var/lib/nginx/.s3cfg: None
ERROR: Configuration file not available.
ERROR: Consider using --configure parameter to create one.

我们的php脚本的在执行的时候, 是以nginx这个用户权限来执行的, nginx会读取自己家目
录的配置文件, 我在ec2-user这个用户的家目录下配置的文件对nginx用户无效, 所以出现
了, 我在命令行下可以通过aws s3的接口把文件上传至S3, 在php脚本中调用外部命令无
法成功的原因了. 查看一下nginx的家目录.

1
nginx:x:498:498:Nginx web server:/var/lib/nginx:/sbin/nologin

我们把ec2-user家目录下的.aws这个文件拷贝到/var/lib/nginx/这个目录下, 在php脚
本中调用外部的aws s3接口就可以把文件上传到S3了.

下次多注意用户权限的问题了!