首页 > 解决方案 > nodejs中shell命令的跟踪过程

问题描述

我想要:

  1. 下载一个大的 zip 文件 ( curl),
  2. 如果 #1 成功,将文件解压缩到目标目录 ( unzip)
  3. 如果 #2 成功,则删除文件 ( rm)

我正在编写一个简单的nodejs脚本来执行上述操作,并且正在child_process.execSync为此使用。

const execSync = require('child_process').execSync
execSync(`curl --output ${source} ${target}`)
execSync(`unzip -q ${target} -d ${target-dir}`)
execSync(`rm ${target}`)

我正在使用的*sync版本exec来确保事情按顺序发生。由于这些是长时间运行的进程(包含大量文件的大型 zip 存档),我希望随着时间的推移看到进展。我可以使用类似的东西,npm progress或者,因为curl并且unzip已经显示出进步,我不介意只使用它。我该如何实现这一目标?

更新:这是我迄今为止尝试过的。我可以获得一个下载进度条,但我一直盯着空白屏幕unzip(这确实需要很长时间,因为存档真的很大)。我可以在unzip没有 quiet 选项的情况下简单地执行,q但随后我会得到每个解压缩文件的列表。我不想要那个。我只是想要一个进度条。我尝试使用节点模块unzip和其他类似的模块,但它们不起作用。

const spawn = require('child_process').spawn
const ProgressBar = require('progress')
const http = require('http')
const fs = require('fs')

const target = fs.createWriteStream(target_file)
const req = http.request({ hostname: hostname, path: filename })

req.on('response', function(res) {
    const len = parseInt(res.headers['content-length'], 10)
    
    const bar = new ProgressBar(`downloading ${hostname}/${filename} [:bar] :rate/bps :percent :etas`, {
        complete: '=',
        incomplete: ' ',
        width: 20,
        total: len
    })

    res.on('data', function (chunk) {
        bar.tick(chunk.length);
        target.write(chunk);
    })

    res.on('end', function () {
        target.end(function () {
            console.log(`downloaded ${len} bytes to data/${filename}`)
            
            const unzip = spawn('unzip', ['-q', filename, '-d', target_dir])
            
            unzip.on('close', (code) => {
                console.log(`unzip exited with code ${code}`)

                const rm = spawn('rm', [new_filename])
                rm.on('close', (code) => {
                    console.log(`rm exited with code ${code}`)
                })
            })
        })
        
    })
}).on('error', (err) => {
    console.log('Error: ', err.message)
})

req.end()

标签: node.jsexec

解决方案


推荐阅读