从本地机器上的 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 实例

无法从我的ubuntu EC2计算机连接到AWS DocumentDB

反向 ssh 隧道不暴露 ec2 上的端口

AWS EC2 Windows实例无法通过公共IP访问

如何访问在 AWS EC2 Ubuntu 的本地主机上运行的 Parse 服务器?