从本地机器上的 ubuntu (AWS EC2) 读取文件?
Posted
技术标签:
【中文标题】从本地机器上的 ubuntu (AWS EC2) 读取文件?【英文标题】:reading in a file from ubuntu (AWS EC2) on local machine? 【发布时间】:2020-03-19 15:10:16 【问题描述】:我有一个在 AWS 上运行的 python 脚本(带有 Ubuntu 的 EC2 实例)。这个 python 脚本每天输出一个 JSON 文件到 /home/ubuntu 中的一个目录:
with open("/home/ubuntu/bandsintown/sf_events.json", "w") as writeJSON:
file_str = json.dumps(allEvents, sort_keys=True)
file_str = "var sf_events = " + file_str
这里的一切都按预期工作。我的问题是我不确定如何将这个 JSON(存在于 ubuntu 上)读入我在本地机器上运行的 javascript 文件中。
如果我从 ubuntu 调用文件,Javascript 找不到文件:
<script src="/home/ubuntu/bandsintown/sf_events.json"></script>
换句话说,我想将我在云中创建的 JSON 读取到我本地计算机上存在的文件中。我应该在 home/ubuntu 以外的地方输出 JSON 吗?或者,我的本地文件能否以某种方式将 /home/ubuntu 识别为文件位置?
提前致谢。
【问题讨论】:
【参考方案1】:出现问题是因为文件不存在在您的本地计算机上,仅在正在运行的 EC2 实例上。
一种可能的解决方案是将 JSON 文件从 EC2 实例上传到 S3,然后将 JSON 文件下载到您的本地机器/home/ubuntu/bandsintown/sf_events.json
。
首先,在运行 EC2 实例AWS CLI 上安装 AWS CLI 工具包并在终端中运行以下命令
aws configure
aws s3 cp /home/ubuntu/bandsintown/sf_events.json s3://mybucket/sf_events.json
或者安装Python AWS SDKboto3并通过python上传
s3 = boto3.resource('s3')
def upload_file_to_s3(s3_path, local_path):
bucket = s3_path.split('/')[2] #bucket is always second as paths are S3://bucket/.././
file_path = '/'.join(s3_path.split('/')[3:])
response = s3.Object(bucket, file_path).upload_file(local_path)
return response
s3_path = "s3://mybucket/sf_events.json"
local_path = "/home/ubuntu/bandsintown/sf_events.json"
upload_file_to_s3(s3_path, local_path)
然后在您的本地机器上通过 AWS CLI 从 s3 下载文件
aws configure
aws s3 cp s3://mybucket/sf_events.json /home/ubuntu/bandsintown/sf_events.json
或者如果你更喜欢 python SDK:
s3 = boto3.resource('s3')
def download_file_from_s3(s3_path, local_path):
bucket = s3_path.split('/')[2] #bucket is always second as paths are S3://bucket/.././
file_path = '/'.join(s3_path.split('/')[3:])
filename = os.path.basename(s3_path)
s3.Object(bucket, file_path).download_file(local_file_path)
s3_path = "s3://mybucket/sf_events.json"
local_path = "/home/ubuntu/bandsintown/sf_events.json"
download_file_from_s3(s3_path, local_path)
或者使用在浏览器内部运行的 Javascript SDK,但我不建议这样做,因为您必须公开您的存储桶并注意浏览器兼容性issue
【讨论】:
【参考方案2】:您可以使用 aws S3
您可以在您的实例上运行一个 python 脚本,该脚本在生成 json 时将 json 文件上传到 s3,并在您可以使用的本地计算机上运行另一个 python 脚本(用于 sqs 队列和 s3 下载配置的脚本)或(用于下载的脚本上传到 s3 存储桶的最新文件)。
案例1:
每当 json 文件上传到 S3 时,您都会在 sqs 队列中收到消息,表明文件已上传到 s3,然后文件会下载到您的本地计算机。
案例2:
当 json 文件上传到 s3 时,您可以运行下载脚本来下载最新的 json 文件。
上传.py:
import boto3
import os
import socket
def upload_files(path):
session = boto3.Session(
aws_access_key_id='your access key id',
aws_secret_access_key='your secret key id',
region_name='region'
)
s3 = session.resource('s3')
bucket = s3.Bucket('bucket name')
for subdir, dirs, files in os.walk(path):
for file in files:
full_path = os.path.join(subdir, file)
print(full_path[len(path)+0:])
with open(full_path, 'rb') as data:
bucket.put_object(Key=full_path[len(path)+0:], Body=data)
if __name__ == "__main__":
upload_files('your pathwhich in your case is (/home/ubuntu/)')
您在本地机器上的其他脚本:
带有sqs队列的download1.py
import boto3
import logzero
from logzero import logger
s3_resource = boto3.resource('s3')
sqs_client=boto3.client('sqs')
### Queue URL
queue_url = 'queue url'
### aws s3 bucket
bucketName = "your bucket-name"
### Receive the message from SQS queue
response_message = sqs_client.receive_message(
QueueUrl=queue_url,
MaxNumberOfMessages=1,
MessageAttributeNames=[
'All'
],
)
message=response_message['Messages'][0]
receipt_handle = message['ReceiptHandle']
messageid=message['MessageId']
filename=message['Body']
try:
s3_resource.Bucket(bucketName).download_file(filename,filename)
except botocore.exceptions.ClientError as e:
if e.response['Error']['Code']=='404':
logger.info("The object does not exist.")
else:
raise
logger.info("File Downloaded")
download2.py 从 s3 下载最新文件:
import boto3
### S3 connection
s3_resource = boto3.resource('s3')
s3_client = boto3.client('s3')
bucketName = 'your bucket-name'
response = s3_client.list_objects_v2(Bucket=bucketName)
all = response['Contents']
latest = max(all, key=lambda x: x['LastModified'])
s3 = boto3.resource('s3')
key=latest['Key']
print("downloading file")
s3_resource.Bucket(bucketName).download_file(key,key)
print("file download")
【讨论】:
【参考方案3】:您基本上需要将文件从远程计算机复制到本地计算机。最简单的方法是使用scp
。在以下示例中,它只是复制到您的当前目录。如果你在 Windows 上,打开 PowerShell,如果你在 Linux 上,scp
应该已经安装了。
scp <username>@<your ec2 instance host or IP>:/home/ubuntu/bandsintown/sf_events.json ./
运行命令,输入密码,完成。与您使用ssh
连接到远程计算机的方式相同。 (我相信你的用户名是ubuntu
)
更高级的方法是通过SSHFS 挂载您的远程目录。设置起来有点麻烦,但是您可以立即访问远程文件,就好像它们是本地文件一样。
如果您想通过 Python 以实用的方式执行此操作,请参阅 this question。
【讨论】:
【参考方案4】:将文件从本地复制到 EC2
您的私钥不得公开可见。运行以下命令,只有root用户才能读取文件。
chmod 400 yourPublicKeyFile.pem
要在您的计算机和实例之间复制文件,您可以使用 FileZilla 等 FTP 服务或命令 scp。 “scp”的意思是“安全复制”,它可以在网络上的计算机之间复制文件。您可以在 Unix/Linux/Mac 系统的终端中使用此工具。
要将 scp 与密钥对一起使用,请使用以下命令:
scp -i /directory/to/abc.pem /your/local/file/to/copy user@ec2-xx-xx-xxx-xxx.compute-1.amazonaws.com:path/to/file
您需要指定正确的 Linux 用户。来自亚马逊: 对于 Amazon Linux,用户名为 ec2-user。 对于 RHEL,用户名为 ec2-user 或 root。 对于 Ubuntu,用户名是 ubuntu 或 root。 对于 Centos,用户名为 centos。 对于 Fedora,用户名为 ec2-user。 对于 SUSE,用户名为 ec2-user 或 root。 否则,如果 ec2-user 和 root 不起作用,请咨询您的 AMI 提供商。 要在没有密钥对的情况下使用它,只需省略标志 -i 并在提示时输入用户的密码。
注意:你需要确保用户“user”有写入目标目录的权限。在这个例子中,如果 ~/path/to/file 是由用户“user”创建的,应该没问题。 将文件从 EC2 复制到本地 要将 scp 与密钥对一起使用,请使用以下命令:
scp -i /directory/to/abc.pem user@ec2-xx-xx-xxx-xxx.compute-1.amazonaws.com:path/to/file /your/local/directory/files/to/download
参考:终端截图
Hack 1:从 EC2 下载文件时,通过归档下载文件夹。
zip -r squash.zip /your/ec2/directory/
Hack 2 : 您可以通过以下命令将所有存档文件从 ec2 下载到。
scp -i /directory/to/abc.pem user@ec2-xx-xx-xxx-xxx.compute-1.amazonaws.com:~/* /your/local/directory/files/to/download
【讨论】:
【参考方案5】:您是否考虑过为此使用 EFS?您可以在 ec2 和 your local machine over a *** or a direct connect 上挂载 EFS?能否不将文件保存在 EFS 上以便两个来源都可以访问它?
希望这会有所帮助。
【讨论】:
以上是关于从本地机器上的 ubuntu (AWS EC2) 读取文件?的主要内容,如果未能解决你的问题,请参考以下文章
无法从 S3 读取 csv 到 AWS 上 EC2 实例上的 pyspark 数据帧
从 Windows 部署到 aws 上的 ubuntu 实例