EDIT: Original title said "bash prompt", but I use "zsh". I accepted #Artur R. Czechowski's answer because it was correct in a bash context and I was able to make mine work with his help. PROMPT is now ' ${ENV}${ENV:+ } %F{249}${PWD/#$HOME/~} %{$fg[green]%}'○' ', just adding the bit about ENV was all I needed.
ORIGINAL POST: As part of my job, I change environment variables frequently. So frequently that I feel I'm going to inevitably going to forget which one I'm in and do something I shouldn't. In case it's relevant to you answering my question, I change environment by running a shell script and my current bash prompt is PROMPT=' %F{249}${PWD/#$HOME/~} %{$fg[green]%}'○' '.
If I'm in a virtual environment, such as venv, then my prompt gets prefaced with (.venv). How do I get something similar with an environment variable such as DB_HOST or whatever variable I want? If DB_HOST changes, I want the bash prompt to change right away and persist.
PROMPT_COMMAND is your answer. Example:
myprompt() {
PS1="${DB_HOST}${DB_HOST:+ }\u#\h:\w\$ "
}
PROMPT_COMMAND=myprompt
It will always display current value of DB_HOST variable.
Related
I have a problem that is puzzling me.
I am inside a docker container on a ubuntu machine using a bash shell.
I want to check if the environment variable called "ENVIRONMENT" used by my code is properly set.
When I do "printenv" I can see the variables:
root#863cf368a72d:/data-cron# printenv
ENVIRONMENT = staging
PYTHON_VERSION=3.9.5
HOME=/root
(etc, can't disclose the full details of the environment variables of this product).
Now, if I do:
root#863cf368a72d:/data-cron# echo $ENVIRONMENT
I get nothing! But if I try with another variable:
root#863cf368a72d:/data-cron# echo $HOME
I get the right answer:
/root
Needless to say, my code doesn't work because the variable "ENVIRONMENT" is set to None
Does anyone have any idea? I am puzzled by the mismatch between printenv and echo, I never saw that happening. Thanks in advance
According to what you posted, you don't have an environment variable named ENVIRONMENT, but one named ENVIRONMENT , as you can see from the space in front of the equal sign. Environment variables can be any string, so this variable is not valid.
While you can't set an environment variable with such an odd name (containing a space) from the shell, you can do so from most other applications. Try to grep for where you have a such a string in your configuration. I would not be surprised if this is found in your docker configuration.
BTW, if you want to see exactly what's in a similarily named environment variable, you could also do a
xxd <(printenv|grep ENVIRONMENT)
which should show you byte by byte the name of the variable, including possible unprintable characters.
Is there a way to have an environment variable, or some similar construct, persist across all bash terminal instances in any given login session?
What I'm trying to do is have a variable prompt, which I can switch (for all terminal windows, future, and maybe also current) at a whim. The process of switching is not too important, but I'd like for it to be a set-and-forget thing.
So far, the best option seems to be to have a set of hardcoded values in .bashrc, which my 'switcher' script would edit, but that seems a bit hacky, and prone to destroying everything if there are any minor errors.
I would go for the easiest solution: Write the data to a file instead of a variable.
You can also create some helpers in your .bashrc to automatically retrieve/set the value. A file seems to fulfil all your requirements.
EDIT: You can also have the helpers set the variable on each login from the file.
There's no way to change the prompt in every active shell at once, but you can define functions to your .bashrc which you can call to change the prompt at will.
use_prompt_1 () {
PS1="\w \$"
}
use_prompt_2 () {
PS1="\u#\h \$"
}
You can also use PROMPT_COMMAND to examine your environment to choose a prompt. Add something like the following to your .bashrc as well:
dynamic_prompt () {
if [[ $PWD =~ some_regex ]]; then
use_prompt_1
else
use_prompt_2
fi
}
PROMPT_COMMAND=dynamic_prompt
What should be the Shell (tcsh) command if i want to change the value corresponding to the key in a properties file. For Example: Key=Value to Key=SomeOtherValue
In tcsh (or csh, for that matter), you use the setenv command to write a value to an environment variable.
setenv Key SomeOtherValue
For more information take a look at any csh reference (because it's more widely used, and tcsh is completely compatible.)
For example, see here.
Update: OP has now clarified the the wants to edit the content of a properties file, not an environment variable.
Here is a good SO question/answer that solves this different problem nicely. It uses bash, but translating should be easy.
Changing contents of a file through shell script
Currently my Windows Git Bash shell prompt looks like this:
UserName#ComputerName Path (Branch)
When I echo $PS1, I get:
\[\033]0;$MSYSTEM:\w\007\]\n\[\033[32m\]\u#\h \[\033[33m\]\w$(__git_ps1)\[\033[0m\]\n$
In my .bashrc file I tried to update this like so:
PS1="\[\033[32m\]\w$(__git_ps1)\[\033[0m\]\n$"
What happens is that I lose the UserName#ComputerName which is what was intended. However for some reason, the $(__git_ps1) also disappeared.
When I however do it like this: PS1=${PS1:46} it works as expected.
My plan was to add some additional changes (replace a fixed path with nothing) so the substring method is less then optimal.
What's going on?
UPDATE:
When I execute the PS1="\[\033[33m\]\w$(__git_ps1)\[\033[0m\]\n$" in the shell directly, it also works as expected.
The problem is that due to the double quotes, $(__git_ps1) expands when you define the prompt rather than when the prompt is later drawn.
It works in the shell directly because by defining it again, you cause $(__git_ps1) to be expanded again for the directory you're in. If you change branch, you'll see that it's stuck.
The solution is to use single quotes so that $(__git_ps1) becomes a literal value in the prompt, to be evaluated later:
PS1='\[\033[33m\]\w$(__git_ps1)\[\033[0m\]\n$ '
Execution of
user#EWD-MacBook-Pro:~$ export property.name=property.value
Gives me
-bash: export: `property.name=property.value': not a valid identifier
Is it possible to have system properties with dot inside? If so how do that?
As others have said, bash doesn't allow it so you'll have to use your favourite scripting language to do it. For example, in Perl:
perl -e '$ENV{"property.name"} = "property.value"; system "bash"'
This will fire up a subshell bash with the property.name environment variable set, but you still can't access that environment variable from bash (although your program will be able to see it).
Edit: #MarkEdgar commented that the env command will work too:
env 'property.name=property.value' bash # start a subshell, or
env 'property.name=property.value' command arg1 arg2 ... # Run your command
As usual, you only require quotes if you need to protect special characters from the shell or want to include spaces in the property name or value.
I spent better part of this afternoon trying to figure out how to access some property set by Jenkins (to pass a job parameters jenkins uses property format with a dot) - this was a good hint from Adrian and yes it works for reading properties in the script too. I was at a loss as to what to do but then I tried:
var=`perl -e 'print $ENV{"property.name"};print "\n";'`
This worked quite well actually. But of course that works in a shell that was started with the property set in the environment already i.e. in Adrian's example this could work in a script started from bash instance invoked in perl example he provided. It would not if this perl sniplet was put in the same shell only directly after his perl example.
At least I learnt something this afternoon so not all this time is a waste.
If you export those properties to run an application, some programs can support setting system property as an option, and allow . in the property name.
In Java world, most of tools support setting system property by -D option, e.g. you can set system property with dot like this -Dproperty.name=property.value.
Bash only permits '_' and alpha numeric characters in variable names. The '.' isn't permitted.
http://tldp.org/LDP/abs/html/gotchas.html