EXEC Node has problems with folder name with "+"

I was using the EXEC node recently and I have Node-RED installed in Windows 10. I had "File not found" error when trying to run "COPY". I could rename the file using "RENAME", but then I had to create the original file name again... (file name does not contain "+") I found myself in a work-around nighmare.

The trouble was my folder name in one of the sub-folders had a "+" in the name. This yeilded no issues in any way prior to this, either with CMD terminal or File explorer using the same commands. Using EXEC did not work for "COPY". I renamed the folder replacing the "+" with an underscore and that fixed the issue with the EXEC node.

A quick search yeilds "+" is an acceptable character in folder names.

so any byte except NUL, \, /, :, *, ?, ", <, >, | and you can't have files/folders call . or .. and no control characters (of course).

Just spit balling:
Open the CMD box and try to do the command you want to do there.
Does it work?

In the exec node, how are you constructing the command?
Can you copy/paste the command from the exec node here?

its simple. for example COPY C:\data\Part+Items\PartLog.sts C:\data\Part+Items\20221120.sts. Again, its no worry because I renamed the folder to "Part_Items". As soon as I changed the folder name it found the file and the COPY command works fine. And yes, of course, did that CMD terminal test and it works as scripted. That is why I'm commenting on it. This seems to be a flaw in the EXEC node for reaching folders with certain characters.

Yes Windows is perfectly happy with a + in a file/directory name, as is Linux.

I checked NR on Linux: exec cp /home/pi/test+file /home/pi/test+directory works, so it's not that the node is somehow using + as an operator.

Does it work if you wrap the pathnames in quotes?

Can you raise an issue on GitHub?

Not sure about that one. Interesting, it might just do it. Thanks for the input.

Not sure why you would use exec to do this when node.js can do it with one of its core libraries? Does it work with that?

@TotallyInformation,
I'm confused a bit. Isn't that is what the EXEC node is for?.... Otherwise if it is not recommended, have them please remove the EXEC node from installation.

but, OK, please help me with your suggestion. Context please. Which node do I use to process a command to the OS and do things like copy, move files? Are you recommending that I do it in a function? I have not done this kind of thing before in Javascript and I guess I can look it up fine, if that's what your saying.

The exec node can be used to do anything that the system is capable of doing, but where there is a choice between using a node rather than exec it is generally better to use the node rather than incur the overheads of shelling out to the system. Also using a node red node may be more portable across systems and OSs.

1 Like

I expect it's possible to combine a Read file node and a Write file node to copy a file from one place to another.
It would never occur to me to do so though. Copying a file is an operating system function and it can be easily done with a single exec node.

Are the "overheads of shelling out to the system" really less than the overhead/risk of reading an arbitrary sized file into memory and writing it out to a new location?
Hard to imagine that a javascript application can equal the efficiency of operating system utilities for filesystem operations.

Maybe look at this node - node-red-contrib-fs-ops (node) - Node-RED

Oh, a contrib node. Platform independent though.
Maybe the OP can try it and report back if it works on WIndows with "unusual" characters in the filenames?

That's a little strong wouldn't you say? Each core node has its use and someone slaved over it to put it in the core product.

Exec node is for when you can only do something using an operating system command. But file management doesn't have to be done via OS commands, there are lots of ways.

Since Node-RED is written using Node.js, the node.js libraries can be referenced in a function node. But to do so, you will need to create a reference to node.js's native fs library. You can do this by creating a global reference in settings.js or, more comfortably, by turning on external module support in settings.js and adding a reference in a function node:

    /** Configure how the runtime will handle external npm modules.
     * This covers:
     *  - whether the editor will allow new node modules to be installed
     *  - whether nodes, such as the Function node are allowed to have their
     *    own dynamically configured dependencies.
     * The allow/denyList options can be used to limit what modules the runtime
     * will install/load. It can use '*' as a wildcard that matches anything.
     * NOTE that external modules are installed to `<userDir>`
     */
    externalModules: {
        // autoInstall: false,   // Whether the runtime will attempt to automatically install missing modules
        // autoInstallRetry: 30, // Interval, in seconds, between reinstall attempts
        // palette: {              // Configuration for the Palette Manager
        //     allowInstall: true, /** Enable the Palette Manager in the editor */
        //     allowUpdate: true,  /** Allow modules to be updated in the Palette Manager */
        //     allowUpload: true,  /** Allow module tgz files to be uploaded and installed */
        //     allowList: ['*'],
        //     denyList: [],
        //     allowUpdateList: ['*'],
        //     denyUpdateList: []
        // },
        // modules: {              // Configuration for node-specified modules
        //     allowInstall: true,
        //     allowList: [],
        //     denyList: []
        // }
    },

You can then reference the fs library object in your function node javascript.

File system | Node.js v18.12.1 Documentation (nodejs.org)

File system | Node.js v18.12.1 Documentation (nodejs.org)

If you want to get something even better than the native fs library, specify the fs-extra module instead.

jprichardson/node-fs-extra: Node.js: extra methods for the fs object like copy(), remove(), mkdirs() (github.com)

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.