简体   繁体   中英

NodeJS Exec cp with brace expansion gives different results. Why?

I have a grunt-shell command which cp images files using brace expansion.

file: Gruntfile.js
cpImgTmp: {
    command: 'cp ./app/images/{*.png,*.jpg,*.ico} tmp/images' 
}

When I run this grunt-shell command on MacOS, it does what is expected but returns 'cannot cp...' error on ubuntu.

I've searched through grunt-shell lib and noticed it uses exec function. I tested the command once more in a controlled environment

exec('cp ./app/images/{*.png,*.jpg,*.ico} tmp/images')

and verified exec function's spawn args are the same:

['/bin/sh', '-c', 'cp ./app/images/{*.png,*.jpg,*.ico} tmp/images']

I successfully executed the command inside ubuntu server terminal. So my question is the problem with nodejs handling of brace expansion in different environments and what options can I pass to nodejs to make this command work cross unix OS?

I figured this is less of a nodejs problem but a unix shell issue which nodejs could avoid.

The issue is sh doesn't support brace expansions, bash does. On my Mac, sh is symlink to bash and ubuntu (18.04) sh is symlink to dash (by the results this obviously doesn't support brace expansion).

Solution is to pass {shell: '/bin/bash' } for brace expansion to work in unix systems instead of the default '/bin/sh' shell.

example using NodeJS exec function: `exec('cp ./app/images/{ .png, .jpg,*.ico} tmp/images', {shell: '/bin/bash'})

example using grunt-shell

cpImgTmp: {
    command: 'cp ./app/images/{*.png,*.jpg,*.ico} tmp/images',
    options: {
        execOptions: {shell: '/bin/bash'}
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM