I'm currently working on a Node.js project, and would like to automate the setting of environment variables. I've written a script (set_env.ps1) that looks something like this:
Write-Host "Setting environment variables...";
$env:CLIENT_KEY="xxxxxxxxxxxxxxxx";
$env:CLIENT_SECRET="xxxxxxxxxxxxx";
[etc]
And I call this from some npm scripts:
"scripts": {
"install:windows": "powershell ./set_env.ps1",
"start": "npm run install:windows && node index",
"monitor": "npm run install:windows && nodemon index"
},
It doesn't seem to work though. I can enter those same commands manually, one at a time, in the command line, and environment variables are set. Just by running the script, though, "Setting environment variables..." prints to the powershell prompt, but no variables get set.
Everything on the Internet seems to want to do this from the prompt, one env var at a time. This is extremely tedious with a long list of environment variables, and the embedded Powershell prompt in Webstorm has a habit of not accepting pasted strings.
Answering this question because it's likely somebody else will run into this issue.
As the two comments indicated, a Powershell script process's environment is lost on termination. Therefore, environment variables set inside the script won't get passed to the Powershell prompt.
Instead of chaining npm scripts to call everything we need, instead we can call npm run monitor or npm run start from the powershell script, like so:
Write-Host "Setting environment variables...";
$env:CLIENT_KEY="xxxxxxxxxxxxxxxxx";
$env:CLIENT_SECRET="xxxxxxxxxxxxxxxxxxxxxxx";
[etc]
[...]
Write-Host "Initializing process..."
npm run monitor
Then, we have our npm scripts like so:
"scripts": {
"start:windows": "powershell ./start.ps1",
"start": "node index",
"monitor": "nodemon index"
}
To initiate, run npm run start:windows from the command prompt.
Related
Yarn's not recognized as a cmd command.
I tried installing it globally with 'npm install -g yarn' and adding a path variable to "C:\Users[user]\AppData\Roaming\npm\yarn".
Any other suggestions?
First thing first, you should check you have 16+ node.js installed and, you can check it with
node -v
If it's valid,
run the npm config get prefix it'll give you a path CTRL+C this path
Open the start search and type in env and then click "Edit the system environment variables"
Modify the Environment variables
Add the copied path to you PATH as new
After this you should be good, but if the PS is cannot load the Yarn run this command
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Here a few things you can try:
You may need to close and reopen the Powershell windows because newly added environment variables or updates to them are not automatically reflected to already open shell windows.
Check if your path is correct: it normally is C:\Users\endo\AppData\Roaming\npm on my PC, not C:\Users\endo\AppData\Roaming\npm\yarn as you mentioned.
Try running yarn.cmd or yarn.ps1.
Try CMD instead of Powershell, see if it works that way.
I've searched for days but did not find an answer that worked for my problem.
I want to run a npm script through cmd or Powershell in Windows and pass values for script variables.
I would like the bellow script in package.json:
"scripts": {
"happy-birthday": "echo Happy birthday $NAME and many returns!"
}
To output:
Happy birthday Danny and many returns!
With a command like:
npm run happy-birthday --NAME=Danny
Everything I tested so far gives me:
Happy birthday $NAME and many returns!
It feels like npm does not recognize this as a variable and prints it like it is a string. I also tested %NAME%.
Npm version - 6.12.1
You can't pass arguments to the middle of npm scripts, argument(s) can only be passed to the end of them. See my answer here for further explanation.
Given your example, consider the following solution which will work successfully across all platforms:
In your package.json file define your happy-birthday npm script as follows:
"scripts": {
"happy-birthday": "node -e \"console.log('Happy birthday %s and many returns!', process.argv[1] || 'Jane')\""
}
Then run the following command via cmd or Powershell (or any other command line tool).
npm run happy-birthday -- Danny
This will print:
Happy birthday Danny and many returns!
Note: If you just run the following command, i.e. without passing an argument:
npm run happy-birthday
It will print the default name instead:
Happy birthday Jane and many returns!
Explanation:
The npm script utilizes the nodejs command line option -e to evaluate the inline JavaScript as follows:
console.log('Happy birthday %s and many returns!', process.argv[1] || 'Jane')
The arguments passed via the CLI, e.g. Danny, are read using process.argv - whereby we reference the Array element at index 1.
The Logical OR Operator, i,e. || is utilized to return Jane when no argument is passed.
Edit: Setting environment variables instead
Alternatively may want to consider setting an environment variable and referencing it in your npm script.
In your npm script define your happy-birthday npm script as follows:
"happy-birthday": "echo Happy birthday %NAME% and many returns!"
Note the %NAME% notation used by Windows only to reference the variable.
Using cmd
When using cmd (i.e. Command Prompt) you'll need to run the following command:
set NAME=Danny&& npm run happy-birthday
Using Powershell
When using Powershell you'll need to run the following command instead:
$env:NAME="Danny" ; npm run happy-birthday
Note: The default shell that npm utilizes for npm scripts is sh on *nix and cmd on windows. Therefore the aforementioned methods defined in steps 1 and 2 will fail on *nix platforms.
If cross-platform support is requirement and you do want to take this approach of setting environment variables and referencing them via npm scripts, then consider utilizing the cross-env package.
My pyenv is working just fine, but it does not seem to be running my activate script located at /usr/local/var/pyenv/versions/project/bin/activate.fish
When activating my environment it gives the following output, but it does not echo anything from the activate script, which indicates that it is not running.
dani#localhost ~/d/project> pyenv activate project
pyenv-virtualenv: prompt changing not working for fish.
Of course I can just source the file manually, but I'm too eager to find out why it is not running. Is there some kind of debug mode? I'm not sure how to approach.
Actually,
Virtual environment is activated but the message just says that your prompt wasn't changed. Updating prompt was intentionally removed from fish shell.
you can find detailed information here;
https://github.com/pyenv/pyenv-virtualenv/issues/153
If you want to see virtual environment is really activated or not,
run the following command;
pyenv which python
it should print something like;
.pyenv/versions/{your-virtual-env}/bin/python
try this:
set PYENV_ROOT $HOME/.pyenv
set -x PATH $PYENV_ROOT/shims $PYENV_ROOT/bin $PATH
pyenv rehash
I'm trying to set environment variables through the commands module within cfn-init.
"commands": {
"set-env": {
"env": {
"HOSTNAME": "fb-iaas.elevatebilling.com"
},
"cwd": "~",
"command": "echo \"$HOSTNAME\" > test.txt"
}
},
And this is the output I see in cfn-init.log
2016-09-22 10:26:53,638 DEBUG Running command set-env
2016-09-22 10:26:53,639 DEBUG No test for command set-env
2016-09-22 10:26:53,655 INFO Command set-env succeeded
2016-09-22 10:26:53,655 DEBUG Command set-env output:
But environment variable HOSTNAME doesn't get updated. Can someone please explain what am I doing wrong?
Thanks
When you say that the variable doesn't get updated, how have you found this out? Did you open "test.txt" and read what was piped to it or did you ssh into the instance and run an "echo $HOSTNAME"? The reason why I ask is because the AWS docs on running commands with cfn-init (http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-init.html) say this for the "env" option:
env -
Optional. Sets environment variables for the command. This property
overwrites, rather than appends, the existing environment.
From my interpretation of this and from my experience, environment variables set using "env" exist only for the command in which it resides. If you read in the "test.txt" file that the variable is set to what you want but not when you run an "echo $HOSTNAME" it's because the variable exists only for the command. I suggest that if you want your environment variables to persist, you set them using "export" in the UserData section of the Cloudformation template.
The AWS documentation gives the syntax for Linux. Since your script starts with echo, I suppose you are running Windows. In that case, the environment variable syntax should be %HOSTNAME%, instead of $HOSTNAME.
I have script lets say:
C:\foo.bsh
I want to be able to run this command via the windows run command:
Start -> Run
Windows Key + R
and type something small like 'foo' and hitting return.
However, I do not want a cmd prompt to be visible. This script does some preprocessing for an IDE. I do not want the cmd prompt to be open for the lifetime of the IDE process.
I have tried:
1) Creating a bat file with the following contents:
c:\cygwin\bin\bash --login "C:\foo.bsh" (this fails because it keeps a cmd open)
2) Converting the above bat file to an exe using bat_2_exe_converter (does not make the cmd silent)
thoughts?
EDIT: The solution so far suggests something to type from an actual cygwin shell. I am trying to get a faster solution by having something short I can type in the Windows run command. Also, the nohup command; exit doesn't automatically kill the box - however I can manually kill it without killing the IDE process. The run command accepts shortcuts (.lnk's), bat's, exe's.
Try the run.exe command of cygwin. It is a big install, a complete unix environment for your Windows machine. Suppose you installed it at c:\cygwin\.
No mystery, just run c:\cygwin\bin\run.exe <your command here> and you will have your no dos window execution.
You can run it from any DOS window (run cmd.exe from the start menu). You don't need to run it from cygwin.
To make it easier, append C:\cygwin\bin to your %PATH% env var (My Computer → Properties → Advanced → Environment Variables) (Kudos to Felipe Alvarez comment).
Now you can just type
c:\cygwin\bin\run.exe "C:\foo.bsh"
You must create a link in your Start Menu with this command so will be able to run it with Win-R.
Here is the man page of the runcommand:
$ man run
RUN(1) run 1.3.0 RUN(1)
NAME
run - start programs with hidden console window
SYNOPSIS
run [ -p path ] command [ -wait ] arguments
runcommand [ -p path ] [ -wait ] arguments
DESCRIPTION
Windows programs are either GUI programs or console programs. When
started console programs will either attach to an existing console
or create a new one. GUI programs can never attach to an exiting con‐
sole. There is no way to attach to an existing console but hide it if
started as GUI program.
run will do this for you. It works as intermediate and starts a pro‐
gram but makes the console window hidden.
With -p path you can add path to the PATH environment variable.
Issuing -wait as first program argument will make run wait for program
completition, otherwise it returns immediately.
The second variant is for creating wrappers. If the executable is
named runcommand (eg runemacs), run will try to start the program (eg
emacs).
EXAMPLES
run -p /usr/X11R6/bin xterm
run emacs -wait
runemacs -wait
run make -wait
AUTHORS
Charles S. Wilson
Harold L Hunt II
Jehan Bing
Alexander Gottwald
Version 1.3.0 November 2005 RUN(1)
You can use either...
c:\cygwin\bin\bash -l /path/to/script_to_interpret.sh
...or...
c:\cygwin\bin\bash -l -c /path/to/executable_script.sh
Note: the -l flag tell bash to "act as if it had been directly invoked by login" and use Bash Startup Files. This is important in that it sets your $PATH and other things you rely on when you launch a cygwin terminal. If you don't include -l or --login you will get "command not found" when you try to call anything except of a bash builtin.
The difference between the 2 is like the difference between doing...
bash script_to_interpret.sh
...and...
./executable_script.sh
...in *nix. The former interprets the script using bash. The latter executes the script (only if it has chmod +x executable_script.sh) and interprets it according to its "shebang" line. The latter method is also what you want to do if your executable is not a script at all, like a *nix binary compiled from source.)
It has been bugging me for a while I couldn't find the solution for this, but I finally got the right mix together.
You can simply do the following if you have cygwin on your PATH:
run bash test.js
If cygwin is not on your path, you can do this:
c:\cygwin\bin\run.exe -p /bin bash test.js
If you are looking for more control over the created window (maximize, etc) it looks like you can use cygstart also.
Sources:
- neves answer above (though that wasn't enough by itself for me personally to figure it out)
- http://cygwin.com/ml/cygwin/2008-09/msg00156.html
As the terminal can't close while your script is still running, try the command:
"nohup C:\foo.bsh; exit"
This way your script will be backgrounded and detached from the terminal, and it should exit quickly so the terminal goes away. I think that the window may still 'flash' with this approach, but the results should be better than what you're getting.
I'm running Cygwin64 and the xwin server link points to:
C:\cygwin64\bin\run.exe /usr/bin/bash.exe -l -c /usr/bin/startxwin.exe
This creates an icon AND a notification on the taskbar. I don't like that. The icon is rather useless, the notification has all your menu options from .XWinrc.
So... I wrote a .vbs script to silently run this command and make the icon go away:
Set objShell = CreateObject("WScript.Shell")
objShell.Run("C:\cygwin64\bin\run.exe /usr/bin/bash.exe -l -c /usr/bin/startxwin.exe"), 0
Another imperfect possibility is to run the script via a shortcut and set the shortcut's Run option to "minimized".
Go to the directory where you have installed cygwin(on my machine it is c:/cygwin64/bin)
Once there simply type "bash.exe"