I am trying to set an environment variable on a Mac at boot time. I want the variable to exist even if nobody is logged in. This is because I may use ARD to launch a script remotely (as root) and I need to query these variables.
I can create a PLIST in the LaunchDaemons folder that will perform launchctl command, but this doesn't seem to set the variable for the script that is launched remotely as root (whether someone is logged in or not). However, if a user logs in, it does work for that user.
launchctl setenv ENVNAME ENVVALUE
Information I have found on this (such as https://apple.stackexchange.com/questions/106355/setting-the-system-wide-path-environment-variable-in-mavericks) suggests that it can only be in a user context, on login.
Is anyone aware of a way that a variable can be set so it exists when the machine is booted?
I have found details that are out of date for 10.10 (such as using the .profile or bashrc) which may have helped previously (but I can't be sure).
Related
I have recently started to use GitHub Packages to distribute our shared libraries internally and have retrospectively changed the Gradle build configuration to use credentials based on system environment variables, rather than hard-coded e.g.
repositories {
mavenLocal() // only use when testing -SNAPSHOT locally
mavenCentral() // third-parties
maven { // our-library
name = "MyLibrary"
url = "https://maven.pkg.github.com/MyCompany/mylibrary"
credentials {
username = project.findProperty("git_username") ?: System.getenv("git_username")
password = project.findProperty("git_token") ?: System.getenv("git_token")
}
}
}
Unfortunately no matter how many environment variables I changed, whether in ~/.zshrc or .zshenv or .bash_profile or /etc/launchd.conf the build was indicating that the credentials were prohibited, or more accurately were resolved as nul.
Each time I changed a config I also ran the appropriate source to ensure it was active, I even resorted to rebooting, just in case.
The environment variable would always show in the terminal confirming the environment variable was always set up correctly, e.g. echo $git_username or printenv yielded the environment variable and expected sensitive token.
After a lot of experimenting and with the help of a colleague we determined that launching NetBeans 15 from the dock wasn't helping, so instead we also added the following line to ~/.zshrc
alias netbeans="/Applications/NetBeans/Apache\ NetBeans\ 15.app/Contents/MacOS/netbeans &"
But now to launch NetBeans I can't use the dock icon, but manually launch the terminal and then type
netbeans
Here's the new lines added to ~/.zshrc
#
# RW - For GitHub Package access
#
export git_username=NotApplicableUsesToken
export git_token=redacted1
export git_publish_username=NotApplicableUsesToken
export git_publish_token=redacted2
#
# RW - So Netbeans launches and honours the environment variables above
#
alias netbeans="/Applications/NetBeans/Apache\ NetBeans\ 15.app/Contents/MacOS/netbeans &"
My question is, why didn't NetBeans when launched from the dock discover the environment variables? How should I configure NetBeans to pickup the environment variables without this workaround?
The Aqua GUI doesn't read any of the shell configuration files, e.g. .bash_profile, .bashrc, .login, .profile, .zprofile, or .zshrc. You were correct to start looking at launchd. Unfortunately /etc/launchd.conf is no longer supported and the file is not read.
Apple's Runtime Configuration Guidelines in the Environment Variables section states:
There are two ways to make environment variables available to an application. The first is to define the variables in a Terminal session and then launch the application from the same session. ...
The second way to associate environment variables with an application is to include the LSEnvironment key in the application’s information property list file. ...
Editing an application's plist doesn't seem like the best idea and your changes may be lost when the application is updated.
There is a third approach.
launchctl has setenv, unsetenv, and getenv sub-commands for managing environment variables. However the environment variables are not persisted across launchd instances.
It seems that a common approach is to create an agent job .plist in ~/Library/LaunchAgents that runs at user login to macOS that will execute launchctl setenv to set the environment variables that should be available to applications launched from the dock. There are discussions at "Set systemwide variable with /etc/launchd.conf does not work in 10.10" and "Environment variables for GUI apps" that point to resources for this approach. You may also want to see Creating Launch Daemons and Agents.
I haven't tested or tried this approach myself.
I have this script on an Ubuntu VM that uses an environment variable that is set in a script in /etc/profile.d/appsetup.sh.
The variable is used in my script, server-up.sh, to start my Java app:
export path=$KEYSTORE_PATH
java -jar -Dsecurity.keystore.path=$path [jarfile]
If I echo the variable, it works:
$ echo $KEYSTORE_PATH
/etc/ssl/certs
And if I run the script on my own (sudo sh server-up.sh) it runs and uses the environment variable just fine.
However, when the script is executed from Jenkins' "Execute Shell" step (on the same VM), it apparently can't access the environment variable, even though supposedly it's available system-wide.
I've tried setting the owner of server-up.sh to both root and jenkins and Jenkins runs it either way, but in neither case does it get the environment variables. In Jenkins, I also tried using the command sudo -E /[path]/server-up.sh but then the job fails and an error says sudo: sorry, you are not allowed to preserve the environment.
I've googled a dozen times for various things, but almost everything that comes up is people asking how to set environment variables in Jenkins, and I don't need to do that; I just want a script that Jenkins can execute have access to system environment variables.
What do I need to do to get this working?
Make a small change to allow the /etc/profile.d/appsetup.sh script to output the variable to a file, where the Jenkins job can access this variable to create an environment variable available for your job to run successfully.
I don't think the context and needs are explained sufficiently well to properly answer the question with a here's how you do it.
On a server, jenkins.war launches from a shell (or a root shell which invokes a shell script with commands which launches jenkins), which has an environment and to which you can set and pass parameters. Those exist in the context of the jenkins.war process. If you run from a daemon (initd / systemd) you get a non-in=teractive shell, which is set differently to your normal shell.
Your Jenkins will typically have Nodes launching agents on remote servers. Those are typically launched via a non-interactive shell (so no user .profile settings).
Then the jobs themselves run on one of the agents where the executor launches a shell for the job execution. Sub-shells may be launched for specific steps.
The two context you mention sudo sh server-up.sh and Jenkins' "Execute Shell" step (on the same VM), even on the same VM do not inherit the same environment as the Node is launched on it's own process using a non-interactive shell and is not aware of anything in your server-up.sh script; it (generally) just gets the /etc/profile.
You have options. You can set Global variables within Jenkins: ${JENKINS_URL}/configure
Global Properties
[ X ] Environment variables
[ X ] Prepare jobs environment (requires Env Inject plugin)
The same options also exist at the Node level
You can install the slaves-setup plugin, which allows you some customization when launching agents (aka slaves).
You can install the Environment Injector plugin, which adds the previously mentioned Prepare jobs environment feature.
It also adds jobs specific configuration options for:
[ X ] Prepare an environment for the run
Plus under the Build Environment section,
[ X ] Inject environment variables to the build process
and
[ X ] Inject passwords to the build as environment variables
Those are encrypted, and I believe are masked
Finally, you can add a build step to Inject environment variables, useful if you need to have different values for different steps.
BUT it's certs in a keystore!
Given that you also mention what you are trying to make available is $KEYSTORE_PATH=/etc/ssl/certs, I wonder if you've explored using the Credentials plugin? Is supports a wide variety of credential types, including:
Password
Username and password
SSH private key
Public Certificate and private key
Binary blob data
That OAuth thingy
The obvious benefit to using this approach vs cooking your own is it's been designed to work securely with Jenkins so your secrets don't get inadvertently exposed. Aside from the extensive documentation on the plugin site, there's more in the book on Using credentials, using them in a pipeline which also mentions the Snippet generator will stub it for you, and on the Cloudbees site - Injecting secrets into builds. You can probably find plenty of help here in S/O and DevOps.
You may also wish to explore the newly introduced Git credentials binding for sh, bat, and powershell, though not sure that's applicable in your case.
I installed Mongo on my machine (installed in the Program Files folder), setting up the data and log destinations on another drive.
Upon exit from the Mongo shell, it wants to write the .dbshell file to my User profile folder (C:\Users\Name.dbshell). This process fails, because my username contains diacritic characters, which the Mongo shell parses incorrectly. This throws the following error:
Error saving history file: FileOpenFailed Unable to fopen() file C:\Users\Name and Surname\.dbshell: The system cannot find the path specified.
Can I change the Environment variables of the Mongo application? I've looked in the configuration file and there does not seem to be the appropriate option listed in the comment lines. I haven't been able to find the answer at the configuration page as of yet. I looked at the mongo reference page and while it does mention the Environment variables and associated commands, using these does not seem to do anything and running a Mongo shell will still throw an error upon exit because of incorrect parsing of the path.
My question, then, is, how can I change the default path to which Mongo will write its .dbshell file?
i'm beginer in nativescript,i have correctly install ANDROID_HOME environment variable which return my sdk path after echo $ANDROID_HOME but despite this it return me The ANDROID_HOME environment variable is not set or it points to a non-existent directory. You will not be able to perform any build-related operations for Android
but if i put my project in the same directory with sdk directory it return me
Cannot resolve the specified connected device by the provided index or identifier. To list currently connected devices and verify that the specified index or identifier exists, run 'tns device'
I also notice that after each computer restarting environment variable disappear and i must resume a same process , i have edit .profile file, .bashrc file and zshrc file for environnement variable i have a same result
please tell me what wrong ... thank in advance
my ~./bashrc file
export ANDROID_HOME=/home/user/Android/Sdk
export PATH=$PATH:/home/user/Android/Sdk/tools
export PATH=$PATH:/home/user/Android/Sdk/platform-tools
export LD_LIBRARY_PATH=/home/user/Android/Sdk/emulator/lib64
In /home/user/Android/Sdk should be tools and platform-tools folders.
That's enough for me. (Linux Mint 18)
Maybe this information will be useful to someone:
Linux environment variables configuration files
.bashrc
This file is a variable for a particular user. It is loaded every time the user creates a terminal session, that is, in other words, opens a new terminal. All the environment variables created in this file take effect every time a new terminal session begins.
.bash_profile
These variables take effect every time the user connects remotely over SSH. If this file is missing the system will look for .bash_login or .profile.
/etc/environment
This file is for creating, editing and deleting any environment variables at the system level. The environment variables created in this file are available for the entire system, for each user and even for a remote connection.
/etc/bash.bashrc
System bashrc. This file is executed for each user, each time he creates a new terminal session. This only works for local users, when connected through the Internet, such variables will not be visible.
/etc/profile
System file profile. All variables from this file are accessible to any user on the system only if he entered remotely. But they will not be available when creating a local terminal session, that is, if you just open the terminal.
All the Linux environment variables created with these files can be deleted only by removing them from there. Only after each change, you need to either log out and log in, or execute this command:
$ source file_name
So, the environment variable can be of three types:
Local environment variables
These variables are defined only for the current session. They will be irretrievably erased after the session is completed, whether it is remote access or terminal emulator. They are not stored in any files, but are created and deleted using special commands.
Custom shell variables
These shell variables in Linux are defined for a specific user and are loaded each time it logs in using the local terminal, or it is remotely connected. Such variables are usually stored in configuration files: .bashrc, .bash_profile, .bash_login, .profile or in other files located in the user's directory.
System environment variables
These variables are available throughout the system, for all users. They are loaded when the system starts from the system configuration files: / etc / environment, / etc / profile, /etc/profile.d/ /etc/bash.bashrc.
If you are using nvm to manage different nodejs version, then try disabling nvm and using only one global nodejs version.
Regarding the environment variables that are being volatile, make sure that you track down the proper profile file that is being parse and place your changes there.
It would help if you can be more specific about your current platform. Then, people will be able to respond with more precision.
hi i solve my problem by adding in profile file environnement variable
export ANDROID_HOME=~/Android/Sdk
export ANDROID_HOME=~/Android/Sdk/tools
export ANDROID_HOME=~/Android/Sdk/platforms-tools
then i erased all path generate by all commands line entries from my terminal in .bashrc file(i think that it was that the problem source) . finally it work well thanks a lot to everybody for your helps
I'm using Jenkins to do continuous integration builds. I have quite a few jobs that have much of the same configuration code. I'm in the midst of pulling this all out into a common script file that I'd like to run pre and post build.
I've been unable to figure out how to set some environment variables within that script, so that both the Xcode build command, and the Jenkins build can see them.
Does anyone know if this is possible?
It is not possible to do exactly what you ask. A process cannot change the environment variables of another process. The pre and post and actual build steps run in different processes.
But you can create a script that sets the common environment variables and share that script between all your builds.
The would first call your shell to execute the commands in the script and then call xcodebuild:
# Note the dot in the beginning of the next line. It is not a typo.
. set_environment.sh
xcodebuild myawesomeapp.xcodeproj
The script could look like this:
export VARIABLE1=value1
export VARIABLE2=value2
How exactly your jobs will share the script depends on your environment and use case. You can
place the script in some well-known location on the Jenkins host or
place the script in the version controlled source tree if all your jobs share the same repository or
place the script in a repository of its own and make a Jenkins build which archives the script as a build artifact. All the other jobs would then use Copy Artifact plugin to get a copy of the script from the artifacts of script job.
From Apple's Technical Q&A QA1067 it appears that if you create the file /Users/YOU/.MacOSX/environment.plist and populate it with your desired environment variables that all processes (launched by the user with the environment.plist file in their home dir) will pick up these environment variables. You may need to restart your computer (or just log out and back in) before a newly launched process will pick up the variables.
This article also claims that Xcode will also pass these variables to a build phase script. I have not tested it yet but next time I restart my MacBook I will let you know if it worked.
From http://developer.apple.com/library/mac/#/legacy/mac/library/qa/qa1067/_index.html
Q: How do I set environment for all processes launched by a specific
user?
A: It is actually a fairly simple process to set environment variables
for processes launched by a specific user.
There is a special environment file which loginwindow searches for
each time a user logs in. The environment file is:
~/.MacOSX/environment.plist (be careful it's case sensitive). Where
'~' is the home directory of the user we are interested in. You will
have to create the .MacOSX directory yourself using terminal (by
typing mkdir .MacOSX). You will also have to create the environment
file yourself. The environment file is actually in XML/plist format
(make sure to add the .plist extension to the end of the filename or
this won't work).