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.
Related
I need puppet to execute a script that is inside an installed app. In addition I need to run only if it detects an older version of the and is not on a certain server and then install the new version
I have tried a bunch of stuff and I am losing track. First I tried to use a cd to go to the where the script and then tried running the script directly but I keep getting the same error.
install.pp
# Install required packages
class tripwire::install {
exec { 'uninstall_tripwire':
command => './usr/local/tripwire/te/agent/bin/uninstall.sh',
cwd => '/usr/local/tripwire/te/agent/bin',
path => '/usr/bin/sh',
onlyif => [
"${::fqdn} != 'server.com'",
'/usr/bin/test -f
/usr/local/tripwire/te/agent/bin/uninstall.sh',
"grep -c '8.6.0' /usr/local/tripwire/te/agent/data/version",
],
notify => Exec['install_tripwire'],
I would think this would it would execute the script but all I get is:
Error: /Stage[main]/Tripwire::Install/Exec[uninstall_tripwire]: Could not evaluate: Could not find command 'server.com'
I need puppet to execute a script that is inside an installed app. In
addition I need to run only if it detects an older version of the and
is not on a certain server and then install the new version
The particular task you seem to be trying to perform with your Exec duplicates standard behavior of the Package resource. You really, really ought to manage software via packages, even if you have to do some packaging yourself and maintain a local package repository. The time spent on packaging is easily offset by the time saved managing software, even with Puppet in the mix.
Additionally, as far as controlling which machines to operate upon goes, you ought to be treating that as a matter of classification. If that class should not be applied to machine server.com then it should not be declared into that machine's catalog. If it should be applied differently to that machine than to others, then it should be appropriately parameterized, and those parameters used (at classification time, maybe with the help of Hiera) to select the appropriate behavior for each target machine.
Nevertheless, with respect to the code actually presented, the error message
Could not evaluate: Could not find command 'server.com'
reflects that this element of your onlyif array ...
"${::fqdn} != 'server.com'",
... is not a command. onlyif requires a command or an array of them that can be executed on the target system, so maybe this, instead:
"test ${::fqdn} != server.com",
Additionally, this looks wrong:
command => './usr/local/tripwire/te/agent/bin/uninstall.sh',
Remove the leading ., unless you really intend to resolve that path against the working directory. And if you do intend to resolve it as a relative path then I urge you to instead expand it to an absolute one.
Furthermore, this probably doesn't do what you intend:
path => '/usr/bin/sh',
The path attribute names a binary search path, like the PATH environment variable. You may indeed want to specify one, such as maybe '/bin:/usr/bin:/sbin:/usr/sbin', but if the intention of what you did put was for the commmand to be executed via a shell, then you were looking for
provider => 'shell',
When I press Ctrl+C in PowerShell, I receive:
Terminate batch job (Y/N)?
Similar to https://superuser.com/questions/35698/how-to-supress-terminate-batch-job-y-n-confirmation, except for Windows PowerShell.
Does PowerShell provide any more control over batch jobs than what CMD does?
The behavior is neither caused by PowerShell nor can PowerShell change it (as evidenced by the PowerShell source-code repo not containing the prompt message).
The behavior is built into cmd.exe - Powershell, in this case, is calling a .cmd file (batch file), which is interpreted by cmd.exe.
If you explicitly control the invocation of the target executable, you can fix this by moving to Powershell - note this has its own considerations, see below.
If you do not explicitly control the invocation of the target executable, you're out of luck (unless you're willing to install third-party cmd.exe replacements) and must press Ctrl+C twice in order to terminate execution.
A[n ill-advised] workaround is to modify the cmd.exe binary - see article with instructions on how to patch the cmd.exe executable in order to suppress the prompt. Additionally, you can post a feature request on GitHub to request that this behavior be fixed at the source, though that is unlikely to happen for reasons of backward compatbility.
To demonstrate the behavior:
The examples assume that Node.js is installed and that node.exe is therefore in your PATH:
First, invoke node.exe directly, with a tight loop that requires you to press Ctrl+C to terminate the process.
PS> node -e "while (true);"
As you'll see, pressing Ctrl+C instantly terminates the process - no confirmation prompt.
Now, let's create a sample batch file that invokes the same command and invoke that batch file:
PS> "#echo off`nnode -e `"while (true);`"" | Set-Content test.cmd
PS> ./test.cmd
As you'll see, pressing Ctrl+C now presents the undesired Terminate batch job (Y/N)? prompt. (You'd get the same behavior if you ran the batch file from cmd.exe.)
To demonstrate that gulp is a cmd file:
You say you're running your command via gulp's CLI.
On Windows, the entry point for the gulp CLI is gulp.cmd [see update in the bottom section] - i.e., a batch file. That is how it works in general for npm-package "binaries" (executables) implemented as either JS files or shell scripts.
That gulp invokes gulp.cmd can be verified as follows:
# Execute from a project folder that has `gulp` installed as a dependency.
# If `gulp` is installed *globally*
# Note: CLI `npx` requires npm version 5.2.0+
PS C:\some\NodeJs\project> npx where gulp
You'll see something like:
C:\some\NodeJs\project\node_modules\.bin\gulp
C:\some\NodeJs\project\node_modules\.bin\gulp.cmd
Note that where.exe also lists the extension-less Unix-shell script, ...\gulp; however, from cmd.exe / Powershell such a shell script isn't directly executable, and it is ...\gulp.cmd - the batch file - that is executed.
(If in doubt, place a command such as #set /p dummy="Press a key" at the start of the gulp.cmd file, and you'll see that this command executes when you invoke gulp without the .cmd extension.
Also note that there is no gulp.exe.)
More generally, on Windows, a project's node_modules\.bin subfolder contains pairs of CLI entry points for the CLIs that come with packages that the project depends on locally:
node_modules\.bin\<some-cli> is the Unix shell script (whose executing interpreter is controlled via its shebang line).
node_modules\.bin\<some-cli>.cmd is the helper batch file for Windows.
Updates and future considerations:
In the context of npm modules, the problem would go away if a PowerShell script (*.ps1) were used as the helper script on Windows. There are tickets for npm, yarn and similar software to do this. There are also some drawbacks:
*.ps1 files aren't directly executable from outside of PowerShell, notably from cmd.exe and File Explorer (and changing that is nontrivial).
PowerShell still hasn't fully replaced cmd.exe as the default shell, as of Windows 10 (and won't anytime soon, if ever).
When called from PowerShell, a *.ps1 file would be found and run in-process, so a possible solution is for the npm project to also provide *.ps1 helper scripts, which would take precedence over *.cmd files of the same name.
Update:
Recent versions of npm (verified in 6.14.10) indeed DO install such *.ps1 files.
Alternative package manager yarn, since v2 does not seem to use batch files anymore at all, so the original problem is bypassed there; (v1, by contrast, still uses batch files (only); upgrading from v1 must be done on a per-project basis see the migration instructions).
As the other answer notes, the correct fix is to replace cmd scripts with ps1 versions.
However another workaround for users of the Hyper shell is 'Hyper yes', a plugin that automatically hits y for you when the prompt comes up.
best way to avoid it is to not start it, in my case, is not to type npm run devStart but instead type nodemon ./server.js localhost 3000
here's how it looks like
#echo off
start /w "" "C:\myfile.bat" 2>nul|findstr /i "termin"
if errorlevel 1 goto bypass
:bypass
echo hello by stexup YouTube channel!
timeout /t 5 >nul
I'm building a command line tool using node/javascript, and want to make it available as an npm module. The tool requires a wrapping shell / windows batch script, but how do I install different scripts for different platforms? In package.json I have
"bin" : {
"lookup-bat" : "./bin/lookup.bat",
"lookup-sh" : "./bin/lookup.sh"
}
but I would like to have the same command name, regardless of platform. Is this possible?
Usually you don t mind about that.
Usually, ./bin/lookup is a js file starting with the appropriate shebang #!/usr/bin/env node.
NPM does the rest.
If the program behavior needs to be different for the runtime OS, you shall implement a sort of if(process.platform.match(/win/)) within your program.
I am trying to figure out if Node package PM2 is installed in the path and executable or not with the following puppet code.
exec { "create symbolic link for pm2":
cwd => "${pm2_link_dir}",
path => ['/usr/bin','/bin','/usr/sbin','/sbin'],
onlyif => "! which node &> /dev/null",
command => "ln -s ../lib/node_modules/pm2/bin/pm2 pm2"
}
It is telling me cannot find command "!". Is this the right way to find out if some program is installed and executable?? And why puppet cannot understand The not operator?? I am working on Redhat master and slave.
And why puppet cannot understand The not operator?
The ! operator is provided by the shell; it is not a command. You are using Exec's default provider (posix) which runs your commands directly rather than via a shell. (Or so it is documented to do. It has recently come to light that sometimes the posix provider runs commands via the shell, in apparent contradiction of its docs.)
It is anyway a bit silly to use ! in an Exec's onlyif attribute, when you could instead drop the ! and switch to an unless attribute instead. And drop the redirection, which also relies on the shell.
Is this the right way to find out if some program is installed and executable?
It is usually better to know whether the program should be available on the specific target node, and where necessary to ensure that it is available. If you must inquire about node state, then it is usually better to do that via a custom fact.
With that said, I don't think your approach is inherently wrong, though of course it will only look for the requested program in the path you specify in the Exec.
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.