Setting environment variables in .screenrc - gnu-screen

I'm trying to write a .screenrc file that I can use to set up for a developing on a particular project - It will start a few screens, cd to the right places, open up the right files in an editor, and set some environment variables needed for testing.
I can't get the environment setup to work.. I've tried putting this in `~/.screenrc:
setenv PATH ~/src/my_proj/bin/:$PATH
This doesn't work, and I think the problem is that after screen sets PATH, the regular shell initialization scripts kick in and change it on me.
I don't want to disable the regular shell init scripts. Is there any way to make screen setenv after the shell is initialized? Or alternatively, can screen set a variable to read-only?

I'd do it with some bash magic instead. Try adding something like this to your ~/.screenrc file:
screen -t "window" bash -ic 'PATH=~/src/my_proj/bin/:$PATH bash'
For more details and to have this set for newly created windows using Ctrl-a Ctrl+c or Ctrl-a c see my answer to a different post: https://stackoverflow.com/a/21717641/1413849

for me the line
setenv PATH /home/someuser/bin:$PATH
in the screenrc file did the trick.
I think the expansion of '~' to '/home/someuser' is bash specific and will not work within the screenrc.

There's no way that screen can change the environment variables of a shell process once that process has launched, nor is there any way to make an environment variable read-only (values are stored in each process's memory, and each process has full access to them).
(Well, there might be some ugly system-specific way to do it, but it's the kind of thing Unix-like systems are designed to keep you from doing.)
You'll need to modify your shell's initialization script so that it retains the existing value of $PATH, possibly adding to it, rather than setting it to some new value ignoring its existing value.
If you want to do this conditionally, you can test for the existence of $STY, which is set only if the shell (or any other process) is running under screen.
Also, screen's setenv command doesn't seem to recognize the ~ character. I tried adding a similar setenv to a temporary screenrc, and $PATH contained a literal ~ character. bash seems to recognize the ~ syntax in $PATH, but other shells do not. Replace the ~ by $HOME, which screen does recognize.

For me, I just set environment in ~/.bash_profile or ~/.bashrc
case $TERM in
screen*)
export PS1='[\u:screen \w]\$ '
;;
*)
export PS1='[\u \w]\$ '
;;
esac
It worked, enjoy it.

Related

Why does `singularity run/exec` automatically bind specific some directories? What is the use case?

I'm familiar with containers, but new to Singularity and I found myself fighting a broken Python installation in a Singularity container tonight. It turns out that this was because $HOME was being mounted into my container without my knowledge.
I guess that I've developed a liking for the idiom "Explicit is better than implicit" from Python. To me, automatically mounting specific directories is unexpected behavior.
Three questions:
Why does Singularity default to mounting $HOME, /tmp, /proc, etc?
So that I can become more comfortable with Singularity, what are some use cases for this behavior?
I see the --no-home flag, but is there a flag to disable all of the default mounts without needing to change the default Singularity configuration?
It's a mixture of design, convenience and technical necessity.
The biggest reason is that, unless you use certain params that say otherwise, Singularity images are read-only filesystems. You need somewhere to write output and any temporary files that get created along the way. Maybe you know to mount in your output dir, but there are all sorts of files that get created / modified / deleted in the background that we don't ever think about. Implicit automounts give reasonable defaults that work in most situations.
Simplistic example: you're doing a big sort and filter operation on some data, but you're print the results to console so you don't bother to mount in anything but the raw data. But even after some manipulation and filtering, the size of the data exceeds available memory so sort falls back to using small files in /tmp before being deleted when the process finishes. And then it crashes because you can't write to /tmp.
You can require a user to manually specify a what to mount to /tmp on run, or you can use a sane default like /tmp and also allow that to be overridden by the user (SINGULARITY_TMPDIR, -B $PWD/fake_tmp:/tmp, --contain/--containall). These are all also configurable, so the admins can set sane defaults specific the running environment.
There are also technical reasons for some of the mounts. e.g., /etc/passwd and /etc/group are needed to match permissions on the host OS. The docs on bind paths and mounts are actually pretty good and have more specifics on the whats and whys, and even the answer to your third question: --no-mount. The --contain/--containall flags will probably also be of interest. If you really want to deep dive, there are also the admin docs and the source code on github.
A simple but real singularity use case, with explanation:
singularity exec \
--cleanenv \
-H $PWD:/home \
-B /some/local/data:/data \
multiqc.sif \
multiqc -i $SAMPLE_ID /data
--cleanenv / -e: You've already experienced the fun of unexpected mounts, there's also unexpected environment variables! --cleanenv/-e tells Singularity to not persist the host execution environment in the container. You can still use, e.g., SINGULARITYENV_SOMEVAR=23 to have SOMEVAR=23 inside the container though, as that is explicitly set.
-H $PWD:/home: This mounts the current directory into the container to /home and sets HOME=/home. While using --contain/--containall and explicit mounts is probably a better solution, I am lazy and this ensures several things:
the current directory is mounted into the container. The implicit mounting of the working is allowed to fail, and will do so quietly, if the base directory does not exist in the image. e.g., if you're running from /cluster/my-lab/some-project and there is no /cluster inside your image, it will not be mounted in. This is not an issue if using explicit binds directly (-B /cluster/my-lab/some-project) or if an explicit bind has a shared path (-B /cluster/data/experiment-123) with current directory.
the command is executed from the context of the current directory. If $PWD fails to be mounted as described above, singularity uses $HOME as the working directory instead. If both $PWD and $HOME failed to mount, / is used. This can cause problems if you're using relative paths and you aren't where you expected to be. Since it is specific to the path on the host, it can be really annoying when trying to duplicate a problem locally.
the base path is inside the container is always the same regardless of host OS file structure. Consistency is good.
The rest is just the command that's being run, which in this case summarizes the logs from other programs that work with genetic data.

IntelliJ IDEA global environment variable configuration

I need to use an envirnoment variable in all of my idea run configurations. I currently use run->edit configurations->and then enter the env variables in selected configuration. However that's very tedious when I need to run isolated test scenarios because each one creates a new run configuration and I need to enter the variables all over again.
I tried to set the env variables in my linux system using export SOME_VAR="some value" in various session profile files: /etc/profile,/etc/bash.bashrc,~/.bashrc,~/.profile but intellij seems to ignore those vars during run, even though when I launch echo ${SOME_VAR} from intellij built-in terminal it displays the correct output.
I also tried using intellij .env file plugin and then set SOME_VAR=some value in .env file in project root. Didn't work either.
I found a solution to set environment variables on IntelliJ that has been working very well for me, and is incredibly simple. Let me show you.
This is the program (you can copy and paste it) we're using to test:
package com.javasd.intelijenv;
import java.util.Map;
public class Main {
public static void main(String[] args) {
Map<String, String> env = System.getenv();
for (String envName : env.keySet()) {
System.out.format("%s=%s%n", envName, env.get(envName));
}
System.out.println("My home directory: " + System.getenv("MY_VAR"));
}
}
This program basically loads all environment variables, show them on the console, and try to show an env variable. Also, it assumes that you had created the MY_VAR env variable before calling IntelliJ IDEA, by doing something like:
$ export MY_VAR="This is my adorable var :)"
$ idea
Please, notice that we're calling IntelliJ IDEA in the same terminal (or session, or window) where we created the environment variable. If you create the variable and call the IDEA from the icon, the solution won't work because the IDEA will create its own session.
So, if run it without the correct configuration you will get something line this in your console:
Please, notice that you have just a few variables, and that MY_VAR is null.
Here's configuration I use to load the environment variables:
Click on the "Select Run/Debug Configurations" in your project and select "Edit Configurations":
Then, click on the the button with "..." on the right side of the "Environment Variables" section:
You'll see a pop-up. Check the checkbox on the bottom-left which has the label "Include parent environment variables":
That's it!!!
If you run your program now you will see something like this on your console:
You can see all the environment variables and, of course, your "MY_VAR" variable, with the right value!
Beyond the Basics
Usually, for security reasons, we don't want to keep all the environment variables visible. What we want to do is to make those variables visible only while the IntelliJ (or our program) is running.
So, no sensitive variables should be visible on the environment neither before you call Intellij nor after you close it.
Also, you want to keep those variables in a file (typically with a .env extension) to make it easy to manipulate and for security reasons.
To achieve this, there are some useful programs (you can Google them), but my favorite one is the env-cmd.
Let's say you have a test.env file with the following content:
MY_TEST_VAR=I live in the test.env file.
If you call IntelliJ by doing this:
$ env-cmd test.env idea
And edit your program to show "MY_TEST_VAR", and run it, you will see this on the IntelliJ's console:
But if you quit the IntelliJ, and look for your variable, you will see that the var doesn't exist (you can use env to confirm):
At this point, I hope you're able to play with your own solutions: create shell scripts with variables set inside, test other programs (direnv, autoenv, etc.), and so on.
Enjoy!
...
In my opinion the real issue is what Mat said.
If you want to launch IntelliJ from a shortcut, then you have to edit it a little bit:
Open the .desktop file, and add /bin/bash -c -i to the beginning of the launch command. The file should look something like this:
[Desktop Entry]
Exec=/bin/bash -i -c "/path/to/idea/bin/idea.sh" %f
Name=IntelliJ IDEA Ultimate
Type=Application
Version=1.0
If Maven is used project specific environment variables can be configured under File->Settings->Build, Execution, Deployment->Build Tools->Maven->Runner
These are reused then in any Maven configuration.
The same mechanism to set the environment variables might also work with different runners.
The problem is, that IntelliJ does not "see" the environment variables that are set in .bashrc (Also to be found in CrazyCoders answer). The easiest way to enable IntelliJ to import those variables is to start it from bash e.g. by typing intellij-idea-community.
I tried various things listed above, and adding the environment variables to the terminal configuration and the Maven build tools worked in some contexts but not others. Then I finally found the place in IntelliJ that actually works for runtime processes. Because why just have one environment variable configuration screen when you can have several and make all but one of them wrong? ^_^
If you edit the template from which your run configurations are created, and add the environment variables to the template, then they should be included in every subsequent run configuration that started with that template.
This is especially useful for the JUnit template, since it will mean that all your custom environment variables will be loaded for unit tests, regardless of the scope from which they're executed (single method, whole test class, whole module). But in general, if you edit the templates first, then any run configuration you create thereafter will inherit your environment variables from the template.
From the top menu: Run → Edit Configurations... → expand Templates tree → (choose a template) → Environment variables: → (enter a semicolon-delimited key-value pair list OR use the input widget)
For the auto-generated JUnit configurations, you should blow away any existing ones, and let IntelliJ recreate new ones as you go; each of these will use the updated JUnit template with your environment variables.
For macOs try adding /Applications/IntelliJ IDEA.app/Contents/bin/idea.properties
...
apple.awt.graphics.UseQuartz=true
apple.awt.fullscreencapturealldisplays=false
idea.jre.check=true
SOME_VAR=some value
As no other answer mentioned it here,
Add your environment variable to /etc/environment , then log out and log in again. IntelliJ will definitely pick it up.
I found another tricky solution :)
At least for Linux users...
Just create some shell script like idea.sh in any suitable location with this content.
#!/bin/bash
export YOUR_ENV_VARIABLE=some value
cd ~/path_to_your_idea_folder/bin
bash ./idea.sh
Make this script executable and run it.
This script will always run your IDE with predefined env variables.
Got to Open 'Edit Run/Debug configurations' dialogs
Go to Modify options
Select Environment variables
New box appears for Environment variables below Active profiles

Program Minecraft Mods without Changing Environment Variables?

I am wanting to program Minecraft mods using forge. I am going through the standard installation to begin creating mods, but I have run into an issue. I ran the code "gradlew setupDecompWorkspace eclipse" and it is telling me "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_Home vairable in your environment to match the location of your Java installation." Is it possible to change something else or do something else that will allow me to program? I also cant change the environment variables.
You can change environment variables, even without being an administrator.
The easiest solution is to use set to temporarily change the environment variable for only your session (IE, it'll get reset when you close your command prompt):
set JAVA_HOME=C:\Program Files\Java\jdk1.8.0_91
gradlew setupDecompWorkspace eclipse
Obviously, you'd change the location given to a different one if you have the JDK in a different location.
If you want to change it more permanently, you can use the setx command. Setx keeps the changes you made between sessions (and, more importantly, you don't need to be an administrator, since changes are only made to your account). Note that running setx doesn't apply the changes to the current command prompt window, only future ones; you'd need to close and reopen command prompt after setting the path.
Run
setx JAVA_HOME "C:\Program Files\Java\jdk1.8.0_91"
and then close and reopen your command prompt, and it should keep the path set. (Note that again, you'd want to use the path for your java installation; also it needs to be surrounded by quotes here).
If you don't want to run set each time, you can probably edit gradlew.bat and put the same set command at the top of it.
Simply open gradlew.bat with a text editor and then put
set JAVA_HOME=C:\Program Files\Java\jdk1.8.0_91
at the top of it (again, replace the path with the correct one for your version).

How to use gitbash instead of windows cmd.exe with meteor Release 0.7.0.1-win2

I am getting started with Meteorjs. I'm a windows user so I downloaded the windows installer package Release 0.7.0.1-win2. I use gitbash for my command line interface and can't get it to recognize meteor. I get the error "sh.exe": meteor: command not found". It works fine in windows command line but I prefer gitbash.
How do I get meteor to work with gitbash?
I have the perfect answer for you since I literally just solved the issue myself.
First of all make sure meteor works in the default windows command prompt. Next open git bash and check if the following command works:
cmd //c meteor
This runs the command meteor as if you were in the command prompt.
Next step is to set up an alias in git bash so you don't have to type that out each time.
Open git bash and enter the following:
vim ~/.bashrc
this will open/create the bashrc file in VIM, press i to insert and type the following:
alias meteor="cmd //c meteor"
Save and exit vim by first pressing the Esc key then press the ":" key. Now you should be able to enter commands in VIM. Type "wq" and press enter which will write into your .bashrc file and exit vim.
Almost there! Now that you are back in git bash, all you need to do is point to your .bashrc file by entering the following:
source ~/.bashrc
Now you will be able to run meteor commands straight from git bash! Hope that helped!
Here's the fix:
The problem is because of .bat files not being handled properly by
MinGW
Go to this directory - C:\Users[your username]\AppData\Local\.meteor
You should see a meteor.bat file there. Create a new file called "meteor" (without any extension and ""). Open it with notepad and paste the following:
#!/bin/sh
cmd //c "$0.bat" "$#"
save the file and now run git bash. You should be able to use meteor command in git bash.
Details
To run a *.bat command from MinGW's MSYS shell, you must redirect the execution to cmd.exe, thus:
cmd //c foo.bat [args ...]
The foo.bat command file must be in a directory within $PATH, (or you must specify the full path name ... using slashes, not backslashes unless you use two of them for each path name separator). Also, note the double slash to inform cmd.exe that you are using its /C option, (since it doesn't accept the -c form preferred by the MSYS shell.
If you'd like to make the foo.bat file directly executable from the MSYS shell, you may create a two line Bourne shell wrapper script called simply foo alongside it, (in the same directory as foo.bat), thus:
#!/bin/sh
cmd //c "$0.bat" "$#"
(so in your case, you'd create script file meteor alongside meteor.bat).
In fact, since this wrapper script is entirely generic, provided your file system supports hard file links, (as NTFS does for files on one single disk partition), you may create one wrapper script, and link it to as many command file names as you have *.bat files you'd like to invoke in this manner; (hint: use the MSYS ln command to link the files).
Credits to: Keith Marshall on SO and rakibul on Meteor Forums
It shouldn't be too hard - you just need to make sure that the meteor.bat file is in your executable. Check with echo $PATH from the bash console if it is already there.
For me, the meteor 0.7.0.1-win installer appended meteor's folder to the path automatically. However, you can add it manually with:
export PATH=$PATH:/path/to/user/folder/AppData/Local/.meteor
(On CygWin my user folder is at /cygdrive/c/Users/adam - I'm not sure what the equivalent path would be on git bash).
If you like, append that line to your ~/.profile to make sure meteor gets added to the path when the console opens.
Finally, on Windows the executable file is meteor.bat. I made a symbolic link to the filename meteor, just so I wouldn't have to type the .bat:
cd /path/to/user/folder/AppData/Local/.meteor
ln -s meteor.bat meteor.
Please have a look at the issue https://github.com/sdarnell/meteor/issues/18
I would suggest maybe creating a trivial wrapper script or alias that invokes LaunchMeteor.exe with the original arguments.
After more research on google I see that there isn't an implemented way to do this yet. The guys at meteor are working on it and accepting pull requests if you have a solution. The conclusion I came to is to use Vagrant and virtualbox to set up a ubuntu vm for meteor development. You can find info at this site: http://win.meteor.com/ on how to install virtual machines and provision to work with meteor.

Display in bash prompt

I am working with bash and still unfamiliar with the difference between .profile, .bashrc, .bash_profile.
My desired result is to have the ruby version and rvm gemset show up on my bash prompt.
I added PS1="\$(~/.rvm/bin/rvm-prompt) $PS1" to .bash_profile (via xcode) and it displays
ruby-1.9.3-p286 John-MacBook-Air:~ john$
What I trying to get is
ruby-1.9.3-p286#rails3 $
With "rails3" being the output of rvm gemset.
How do I get John-MacBook-Air:~ john removed from the prompt?
I tried adding the line in the .profile, and .bashrc with no luck but it seems to work in the .bash_profile. Any clarification between these files would be greatly appreciated. I am running rvm on a Mac.
SOLUTION
include the following to the .bash_profile
PS1='\W \$ '
PS1="\$(~/.rvm/bin/rvm-prompt) $PS1"
the prompt looks like
ruby-1.9.3-p286#rails3 ~ $
This line is the problem:
PS1="\$(~/.rvm/bin/rvm-prompt) $PS1"
What you're saying there is "add my rvm prompt to PS1" and then put the pre-existing PS1 at the end. The system's default PS1 is setting this:
PS1='\h:\W \u\$ '
In that setting \h is the hostname (here 'John-MacBook-Air'), \W is the current working directory with your home directory abbreviated to ~, \u is your user's login name (here 'john') and \$ will show a dollar sign if you are a regular user and an octothorpe (#) if you're logged in as root. On OSX, that is set by default in /etc/bashrc. If you want to change the prompt, you need to customize the latter part of the prompt rather than just re-entering $PS1 as is back into the new setting. Removing the hostname is common, but I would very strongly recommend against removing the current working directory. It's very useful information when in a terminal session. Just my two cents.
To see what you can put there, take a look for information about setting your prompt in Bash.
I am working with bash and still unfamiliar with the difference between .profile, .bashrc, .bash_profile.
That depends on your system configuration. Read the manpage for that. You can also change the behaviour either system- or userwide by including one from the other.
Here are few notes to understand better.
Per-login initialization. (or: session startup) There are startup files which are only executed for login shells. On my system, they only set environment variables. (That makes sense, because environment variables are inherited).
Those may be called /etc/profile or ~/.profile for plain sh. If bash is your shell and you have ~/.bash_profile or ~/.bash_login, it will prefer those (in this order) instead by default.
Note that changes to session startup files have no effect until you login next time. Also, you need to make sure to export variables to the environment like PS1=something ; export PS1.
Per-process initialization. For Plain sh, there is no default per-process initialization file, but you can set the ENV environment variable to point to one. For bash, there is also the BASH_ENV variable, and the ~/.bashrc file. The per-process initialization file is the place where you can store per-process shell settings (those who can't be inherited through the environment), e.g. aliases or function definitions.
If you just want to see if a particular file is executed, you can always echo something, or touch some file like echo TEST or touch /tmp/test.