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'}
}
}