Node-Webkit Child Process Exec - node.js

I want to execute a homebrew command for example
brew list
I followed the documentation and executed it like this:
child = exec('brew', function (error, stdout, stderr) {
console.log(stdout);
console.log(stderr);
});
I am getting a command not found error, and realized that if I do /usr/local/bin/brew as the command it works. However simply using 'brew' should work as well since I can run 'brew' from the command line just as such.
Why is this the case and what does it take to make 'brew' run as a child process in node? I have a feeling part of the issue because the command on node-webkit seems to execute from bin/sh.
Thanks

It may depend on how you're starting node-webkit and how you're setting your PATH. When I start from the command line, it inherits the environment variables from my command-line environment, including PATH. If I start by double clicking in a gui, it inherits from the system (presumably /etc/paths), and any additions I make in my .bashrc/.bash_profile have no effect.
Also, I'm no security expert, but my understanding of best practices would include using an absolute path to the executable you're running, so it's harder to spoof by setting an environment variable. By that measure, you're better off using the full path to brew anyway.

Related

Inconsistencies between node's `spawn` and terminal

I'm trying to run a script from node, and I'm seeing different behaviour compared to if I run it from the terminal and I don't understand why.
I'm trying to do something a little bit out there, in that to save people typing pnpm {scriptName} --filter {packageName} I created a little script that they could run instead. It basically takes scriptName and lists all the available packages they can select from, and then trigger spawns a new process calling that command. Something like:
spawn("pnpm", ["--filter " + packageName, scriptName], { stdio: "inherit" });
Example:
In my particular case, I'm trying to test a script that ends up generating a pnpm --filter #ig/main test:debug.
I'm struggling a little though, in that if I invoke that via a terminal it works fine (test:debug is defined both in .\package.json and .\apps\main\package.json). However if I invoke it via the spawn command in node, then for some reason it invoking the test:debug script in the root, rather than just in apps/main. Does anyone know what that might be the case?
Turns out this was down to the current working directory not being set correctly when using spawn.

Adding a command line script to the user environment whilst installing an application using electron-builder

I'm currently working on a project with Electron 9.0.4 and Electron-Builder 22.8.0 and am faced with a problem that doesn't seem too difficult but there isn't a valid solution online! (At least I couldn't find it)
I have my main program that does all of the UI tasks, and a command line script that does some backend. The reason I have this command line script is so that I can run certain parts of the application without opening the window itself. Everything works fine on my computer. After running npm link, my CL script is added to my environment variables and I can just run it from the console. However, when I try to build with electron-builder, the problem occurs.
If I use my Setup.exe on another computer, the command line script just won't be added to the environment variables and I couldn't find instructions on how to do this in the electron, nodejs, or electron-builder documentation. What I found was a suggestion on another question to add npm -g install as a post-install script, but that had no effect either.
Someone else suggested adding npm link as a post-installation script, but firstly if I am not mistaken this function is not intended for production and secondly it created an infinite loop as npm link triggered the post-installation script over and over again.
Thats how the script is added to the project
"bin": {
"command-name": "/cl.js"
}
Any help is appreciated!
Since I couldn't find a direct solution to my problem and didn't want to look any further for a solution while being able to take a different approach.
I decided to take a step back and look for another method to solve my problem I came to the conclusion that I didn't really need to add a script to the command line. My solution was to look for a certain argument when starting the regular application.
if (process.argv.includes("cli")) { /* Do commandline stuff */ }
When the custom argument is found, I simply run the script that should've been run from the command line. Using this approach, you can create a shortcut to my executable that contains the custom argument and then instead of the application it runs the command line script.

How to run a shell command after saving file in Sublime 3

I've been trying to create a custom shell command to run after saving the file im working on. The command should run in the same location of the file.
I've came up with this, under user-preferences, but with no success.:
"on_post_save_user": [
{
"cmd": ["shell command"]
}
.
Based on your question, I'm going to assume that you're using the Hooks package to be able to run arbitrary commands based on events. If you haven't installed that package yet, then you'll need to do that too; the items talked about here are not available in core Sublime.
This package can execute any arbitrary command that you want, but note that this means Sublime commands; that is commands provided either by the core of Sublime or by packages and plugins that you have installed. Thus including the name of a shell command will not work; Sublime silently ignores commands that you tell it to run that it doesn't know about.
That said, the exec command is available directly in any Sublime installation and can execute any arbitrary shell command or program that you tell it to. This command is what is used to execute a build system, for example.
In fact, most of the keys available in a Build system by default (excluding the keys that tell Sublime when your build should apply) are actually arguments to the exec command that tell it what to execute.
Of particular interest to you is the shell_cmd argument, which takes any arbitrary command that you might enter in a command prompt and executes it.
Based on the documentation of the package in question, the configuration option you want would be something like this:
"on_post_save_user": [
{
// Runs `exec` command
"command": "exec",
// Invokes `exec` with `shell_cmd="google-chrome"`
"args": {
"shell_cmd": "google-chrome"
},
// Runs `exec` via `window.run_command`
"scope": "window"
}
]
With the caveat that I don't use this particular package and I can't verify that this is all that might be required, this tells the package to run the exec command (which is indeed a window command), telling it to execute google-chrome.
Other options may be required to exec to do what you want, depending on what that is. It's also unclear from the package documentation whether it supports the standard build system variables like $file to represent the current file or not, which may or may not be a problem.
Note also that since the exec command is what executes build systems, if show_panel_on_build is turned on in your user preferences (which it is by default unless you turn it off), the exec command will open a panel at the bottom of the window to tell you what the command you're running is doing.

Start script on linux startup

I try to execute a java application at startup in a yocto based linux device. I added a script at /etc/init.d/etic and made it executable. If I call at the shell /etc/init.d/etic start or /etc/init.d/etic stop the application is started an stopped as expected. Then I called on the shell update-rc.d etic defaults and the symlinks were created. According to what I found on the web, this should be enough, but somehow the application is not started. What did I miss? How could I check what is going wrong or is there any minimal example which should work which I can try to extend?
Well, often such issues are due to a different environment when executing the start script by hand, as compared to when it's being run from the init system. For instance, your .profile and .bashrc won't have been sourced, when running from the init system.
You can use eg logger to easily log things from your init-script, and this rather easily find out what goes wrong.

setting environment variables for node.js child process

I have a node webkit app, part of which involves using child processes in node to call pdftk (a separate command line program).
I don't want my users to have to install pdftk or use the command line, so I included pdftk in the packaged version of the node webkit app. If I run this packaged app from the command line, it works fine - and I assume that's because it's using the version of pdftk that's installed on my computer, not the one packaged with the app.
When I try to launch the app by double clicking on an icon in the gui, as I'd want a user to be able to do, I get a node.js error - child process ENOENT. I think that's because when launched through the gui, it doesn't inherit the environment variables (including PATH) from my command-line environment.
I know I can set environment variables as an option when I call the child process, but haven't been able to figure out how to do that correctly. I'm not sure what variable I should set, or what I should set it to. I suppose I'm not sure if it's even possible to call pdftk from within the packaged app, or if I would need to have the user install it on their own computer. Any help would be much appreciated.
I think this might not be about environment variables. I guess when you run from the command line your current working directory (CWD) is where the app is. And I think you set the path to pdftk relative to the node script. When you double click (a shortcut) the current working directory and the path where the node script is located are different so relative paths don't work as expected.
When you use relative paths, always use __dirname to get the path the node script is on and use it to set path to the pdftk file. The path.resolve function can be useful when doing this. Read path.resolve documentation
I strongly recommend you to check this question and answers
How do I get the path to the current script with Node.js?
What is the difference between __dirname and ./ in node.js?

Resources