【问题标题】:Executing a shell script via Node.js won't work using gsutil command to move files to Google Cloud Storage buckets通过 Node.js 执行 shell 脚本将无法使用 gsutil 命令将文件移动到 Google Cloud Storage 存储桶
【发布时间】:2018-07-18 11:18:21
【问题描述】:

我正在尝试通过 node js 应用程序将 Ubuntu 17.10.1 目录移动到谷歌云存储桶。我选择使用子进程模块执行 shell 脚本。脚本如下所示。

#!/bin/bash

echo START $1
declare -r MODEL_NAME=$1
declare -r PROJECT_ID=XXX-XXXX
declare -r JOB_NAME="${MODEL_NAME}_$(date +%Y%m%d_%H%M%S)"
declare -r BUCKET_NAME="gs://XXX-XXXX-mlengine"
declare -r GCS_PATH="$BUCKET_NAME/$JOB_NAME"
gsutil -m cp -r ./training/$MODEL_NAME $GCS_PATH
echo ALL DONE!

当从终端调用时,这将按预期工作。

当我从我的节点应用程序调用它时,它说它找不到 gsutil 并返回错误。我正在使用 child_process execFile 进行外部脱壳。如果我注释掉 gsutil 行,一切都很好。我试过使用“等待”无济于事。之前对 child_proccess_promise 模块的努力产生了错误消息,指出它找不到 gsutil。

const child = execFile('tensor_flow/file_process.sh', [trainingName], (error, stdout, stderr) => {
    if (error)  console.log(error);
    if (stderr)  console.log(stderr);    
    if (stdout) console.log(stdout);
  });

这会产生以下错误消息:

tensor_flow/file_process.sh: line 12: gsutil: command not found
training-prep.js:26
tensor_flow/file_process.sh: line 14: wait: `PID': not a pid or valid job spec
START T2
training-prep.js:27
ALL DONE!

任何帮助或见解将不胜感激,或者...如果您可以直接通过节点向我指出“将目录移动到存储桶”,我想知道这一点。

谢谢, JJ

附言。在这项工作的过程中,我已经对上述所有内容进行了 sudo,并且无论是否使用等待/PID 内容,我都完成了这项工作。

【问题讨论】:

  • 您的问题出在gsutil: command not found。可能是因为(1)谷歌云服务器中不存在 gsutil 或(2)找不到路径。如果是2,则需要提供gsutil的绝对路径。
  • 感谢您的努力。最后,我需要从终端启动代码才能让它在我的项目目录中工作。否则它有一个环境,否则它有一个来自 Ubuntu UI 的环境。

标签: node.js google-cloud-storage child-process gsutil


【解决方案1】:

如果你使用的是 NODE.js,你可以使用Google Cloud Storage Node.js Library.

您应该使用createWriteStream method 将文件上传到您的 GCS 存储桶:

var fs = require('fs');
var storage = require('@google-cloud/storage')();
var myBucket = storage.bucket('my-bucket');

var file = myBucket.file('my-file');

//-
// <h4>Uploading a File</h4>
//
// Now, consider a case where we want to upload a file to your bucket. You
// have the option of using {@link Bucket#upload}, but that is just
// a convenience method which will do the following.
//-
fs.createReadStream('/Users/stephen/Photos/birthday-at-the-zoo/panda.jpg')
  .pipe(file.createWriteStream())
  .on('error', function(err) {})
  .on('finish', function() {
    // The file upload is complete.
  });

如果你想使用 node.js 执行的gsutil 命令进行并行上传,你可以关注this thread。在那里,我将@hexacyanide 的第三种解决方案与官方的gsutil docs 结合起来,它对我有用:

const { exec } = require('child_process');
exec('gsutil -m cp -r /full_path_to_your_directory gs://your-bucket', (err, stdout, stderr) => {
 if (err) {
   // node couldn't execute the command
   return;
 }
 // the *entire* stdout and stderr (buffered)
 console.log(`stdout: ${stdout}`);
 console.log(`stderr: ${stderr}`);
});

child_process 包是一个 Node.js 原生模块。

【讨论】:

  • 我的问题是我有 100 个视频并且想要批量处理。您知道我可以在节点中使用的上传目录到存储桶功能吗?
  • @jackjohnson 我编辑了答案,添加了如何使用 gsutil 命令和 nodejs 进行并行上传
猜你喜欢
  • 1970-01-01
  • 2019-08-30
  • 1970-01-01
  • 1970-01-01
  • 2017-05-31
  • 2019-03-03
  • 2017-11-29
  • 2023-03-28
  • 2022-09-30
相关资源
最近更新 更多