【问题标题】:reading in a file from ubuntu (AWS EC2) on local machine?从本地机器上的 ubuntu (AWS EC2) 读取文件?
【发布时间】: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 识别为文件位置?

提前致谢。

【问题讨论】:

    标签: javascript python ubuntu amazon-ec2


    【解决方案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 VPN or a direct connect 上挂载 EFS?能否不将文件保存在 EFS 上以便两个来源都可以访问它?

            希望这会有所帮助。

            【讨论】:

              猜你喜欢
              • 2019-03-28
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-08-12
              • 2018-06-26
              • 2020-01-23
              • 1970-01-01
              相关资源
              最近更新 更多