1

Im trying to create CLI using node.js and I have some tasks where I need to move a folder from one place to another. So to achieve this I used node.js's child_process. Like this:

const { exec } = require("child_process");

function moveFolder(folder,destination){
    exec(
        `mv ${folder} ${destination}`,
        (error, stdout, stderr) => {
            if (error) {
                console.log("Move error");
            }
            console.log("Move success");
        }
    );
}

This piece of code works when I execute this with bash terminal (git-bash or in Linux). But when I execute it using CMD or PowerShell it throws an error

'mv' is not recognized as an internal or external command.

I know PowerShell and CMD have a command called move to achieve this, and that's why it is throwing the error. But is there a way (library or some other method) to execute these types of commands in all environments? (in Windows (CMD, PowerShell), Linux (bash, zsh), Mac OS (zsh)). How can I achieve this?. Can we detect the shell type and execute different commands?

Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
TRomesh
  • 4,323
  • 8
  • 44
  • 74
  • 1
    Consider letting node take care of it, see this thread: [How do I move files in node.js?](https://stackoverflow.com/questions/8579055/how-do-i-move-files-in-node-js) – Jeppe Jun 06 '19 at 11:09
  • 1
    consider utilizing [shelljs](https://github.com/shelljs/shelljs) it provides portable Unix shell commands (such as [`mv`](https://github.com/shelljs/shelljs#mvoptions--source--source--dest) plus others) for node.js. – RobC Jun 06 '19 at 11:10
  • 5
    If you do not delete the default alias list from PowerShell, you will find that `mv` is aliased to `Move-Item` if you are on Windows. On Linux (and presumably on Mac OS), it will _not_ be aliased, as that would block the native `mv` command. However, one must be careful about using aliases that match commands from other environments, as the cmdlet that the alias expands to may not be (probably won't be) fully compatible with the command from the other environment. – Jeff Zeitlin Jun 06 '19 at 11:21
  • 'move-item' is only aliased in PowerShell 5.x. In PowerShell core the alias was removed. – Moerwald Jun 06 '19 at 12:50
  • @Moerwald The [PowerShell-6.2.1-win-x64.msi](https://github.com/PowerShell/PowerShell/releases/download/v6.2.1/PowerShell-6.2.1-win-x64.msi) still ***HAS*** the alias `mv` assigned to `Move-Item` –  Jun 06 '19 at 14:36
  • Using aliases is asking for trouble. If the code is PowerShell, use `Move-Item`. – lit Jun 06 '19 at 15:06
  • @lotpings, also under Linux? – Moerwald Jun 06 '19 at 17:42
  • The [`exec()`](https://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback)) function on Win uses value of `process.env.comspec` - the default on Win is `cmd.exe`. See [source code](https://github.com/nodejs/node/blob/af883e1f99598492474c13447e2a1895c0c6f1b7/lib/child_process.js#L477). Running `node -p "process.env.comspec"` via _PowerShell_ prints something like;`C:\Windows\system32\cmd.exe`. So the `Move-Item` v's `mv` debate seems irrelevant as node (on Win) will only understand _cmd.exe's_ `move` unless the `shell` option is defined differently. – RobC Jun 06 '19 at 19:00
  • 1
    I guess what I'm trying to highlight in my previous comment is that even though you may be invoking _nodejs_ via _PowerShell_ it will use `cmd.exe` as that's the default shell it utilizes on Windows. – RobC Jun 06 '19 at 19:14

0 Answers0