Exec Node: Allow msg.payload to be redirected to stdin for the process#4880
Exec Node: Allow msg.payload to be redirected to stdin for the process#4880gorenje wants to merge 5 commits intonode-red:masterfrom
Conversation
knolleary
left a comment
There was a problem hiding this comment.
Looks good on review. Have proposed a couple changes to ensure the value passed to the stdin stream is a String or Buffer.
|
@knolleary Updated with your suggestions and also added some specs for testing the feature. The tests work on my linux box but I don't have a windows box to test whether the same is the case on windows - I suspect no since stdin is most probably not handled the same. Using I would correct it if you have a suggestion. |
|
@Steve-Mcl can I get you to test this PR on windows to verify the stdin handling works as expected? |
|
@Steve-Mcl bumping this one - would love a validation this is happy on Windows before I merge. |
There was a problem hiding this comment.
Firstly, it kinda works for Windows.
There is an issue where some piped commands (like piping to SORT or FIND) result in an error of "Cannot find file". The reason for this is unclear. I have spent far to long trying to figure out why some piping on windows node REPL works but fails in Node-RED exec node!
To be clear, this problem already exists. e.g. try running dir /B | sort /R in an exec node today results in this error so its not something new with this PR
See next comment where I realised gitbash was to blame!
My main hold out here is the following:
- The built in docs are not update to reflect new functionality
- Since the piping mechanism is not immediately intuitive (to me) (and I dont know how we could arrange the UI to make it more obvious), I strongly feel examples for this feature should be included.
To help get this over the line, I have created an example flow that I would hope gets included:
[{"id":"6b6b965c0173c9a0","type":"exec","z":"56ae6fc26f43b023","command":"tasklist","addpay":"","addpayTo":"parameter","append":"","useSpawn":"false","timer":"","winHide":false,"oldrc":false,"name":"","x":270,"y":340,"wires":[["b488a29ee1b28f65"],[],[]]},{"id":"b488a29ee1b28f65","type":"exec","z":"56ae6fc26f43b023","command":"findstr","addpay":"payload","addpayTo":"stdin","append":"/i \"node\"","useSpawn":"false","timer":"","winHide":false,"oldrc":false,"name":"","x":400,"y":340,"wires":[["ea381e89d7c11370"],[],[]]},{"id":"2c869f5b32b9c485","type":"inject","z":"56ae6fc26f43b023","name":"","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":175,"y":340,"wires":[["6b6b965c0173c9a0"]],"l":false},{"id":"ea381e89d7c11370","type":"debug","z":"56ae6fc26f43b023","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":570,"y":340,"wires":[]},{"id":"20910f9b01a72b32","type":"comment","z":"56ae6fc26f43b023","name":"ps aux | grep \"node\"","info":"","x":370,"y":140,"wires":[]},{"id":"a25b0de60d1287cc","type":"comment","z":"56ae6fc26f43b023","name":"tasklist | findstr /i \"node\"","info":"","x":380,"y":280,"wires":[]},{"id":"f407dc49122444a6","type":"comment","z":"56ae6fc26f43b023","name":"linux","info":"","x":190,"y":140,"wires":[]},{"id":"d2a0d5724175dd79","type":"comment","z":"56ae6fc26f43b023","name":"windows","info":"","x":200,"y":280,"wires":[]},{"id":"7ac7d3ff2c617d40","type":"exec","z":"56ae6fc26f43b023","command":"ps","addpay":"","addpayTo":"parameter","append":"aux","useSpawn":"false","timer":"","winHide":false,"oldrc":false,"name":"","x":270,"y":200,"wires":[["e5345b90069d923a"],[],[]]},{"id":"83280d96df77ee2c","type":"inject","z":"56ae6fc26f43b023","name":"","props":[],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":175,"y":200,"wires":[["7ac7d3ff2c617d40"]],"l":false},{"id":"e5345b90069d923a","type":"exec","z":"56ae6fc26f43b023","command":"grep","addpay":"payload","addpayTo":"stdin","append":"node","useSpawn":"false","timer":"","winHide":false,"oldrc":false,"name":"","x":400,"y":200,"wires":[["55d070f7234c9e60"],[],[]]},{"id":"55d070f7234c9e60","type":"debug","z":"56ae6fc26f43b023","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":570,"y":200,"wires":[]},{"id":"3a0c6b43d3e8eaca","type":"comment","z":"56ae6fc26f43b023","name":"piping results to stdin","info":"","x":220,"y":80,"wires":[]}]
| this.addpayTo = n.addpayTo; | ||
| if ( this.addpayTo === undefined ) { | ||
| this.addpayTo = "parameter" | ||
| } |
There was a problem hiding this comment.
| this.addpayTo = n.addpayTo; | |
| if ( this.addpayTo === undefined ) { | |
| this.addpayTo = "parameter" | |
| } | |
| this.addpayTo = n.addpayTo | |
| if (['parameter', 'stdin'].indexOf(this.addpayTo) < 0) { | |
| this.addpayTo = 'parameter' // ensure sane value | |
| } |
While under normal conditions, addpayTo would only ever be "parameter" or "stdin". However, being a bit more defensive to bad JSON (looking at you AI generated flows) defensive is not a bad thing :)
PS, if we stick with a simple undefined test, it is is generally considered the more robust and "better" practice to use typeof e.g. if (typeof this.addpayTo === 'undefined' ) {
Ok, no sooner than I post my review do i find the answer! I was running Node-RED from gitbash on windows which was causing the OS to use the GNU variants of So, in short, it seems to work well for windows. |
Good news indeed! I just came over to say that if it doesn't work consistently or support for this in core is not desired since no one wants to use it, then there is always the alternative to have an extra node package that implements this feature. At the moment, there is a rough draft for the node over here, it wouldn't take much to make a proper node package out of it - haven't done so because of this PR. Plus the package can have clear warning that it might or might work under windows, use at own risk software. But if no one is really interested in this - and that seems to be the case - then probably better to leave it out of core. The best code is the code that doesn't exist! Thanks @Steve-Mcl for the effort of testing the feature 👍 |
|
@gorenje with NR v4.1 first beta about to get finalised, do you think you could action those 2 items on this PR please?
|
|
@Steve-Mcl I probably won't spend more time on this feature since in the months of this PR being open, no one has shown any interest in this feature, therefore I doubt it would get used. As I wrote above, the best code is the code that isn't written, so I'd keep this out of core to limit the maintenance effort required. Sorry for the wasted effort but why put code into core that no one will use. I have definitely come to realise that this isn't a feature that will get a lot of traction. |
|
Fair enough @gorenje - Appreciate the PR and the decision you made to close it. |
Proposed changes
This adds the ability to pass the
msg.payloadinto the stdin of a process started using the exec node.This was discussed in the forum. The idea is that instead of doing
who | wc -lin an exec node, it's more Node-RED-like to use an exec node that callswho, which pushes stdout to msg.payload, the msg is then passed to a exec node that passes msg.payload to stdin for thewc -lcommand.This works best if the value (i.e. msg.payload) is a string, no provision is made to convert a value to a string that can be passed into a stream.
Checklist
npm run testto verify the unit tests pass