That might be a trivial question, but what is the right way to use builtin variables in a shell script? For example, if I want to write a script that opens default text editor, which is specified in $EDITOR. Just using
export EDITOR
won't help. I found out that defining EDITOR variable helps to solve that problem:
#!/bin/bash
export EDITOR=vim
$EDITOR
The above will work, but is there a way to export the variable without defining it? Thanks in advance.
EDITOR is not a "builtin" variable, and you can export it (i.e. make it an environment variable) whenever you like. Nothing magical here. While it is true that bash interprets this variable in certain situations, it is quite common that applications access this variable, when they want to launch an editor, so in practice, EDITOR is usually exported. For example, I have in my .zshrc and .bashrc the line
export EDITOR=nano
To your question: You can export a varible with an empty falue, like this
export EDITOR=
but I don't see what you will gain from it.
If you just want to ensure, that your shell script and all descendent processes have EDITOR set, a common idiom is
: ${EDITOR:=vim}
export EDITOR
If the user of your script doesn't define this variable, it is set here - you just need two lines, because bash syntax does not permit to combine this into a single one.
Related
If I want to inherit environment variables to child processes, i do something like:
export MYVAR=tork
Assume I have a a file site.conf containing assignments of values (that can contain spaces) to variables:
EMAIL="dev#example.com"
FULLNAME="Master Yedi"
FOO=bar
Now I would like to process this file whenever I open a new shell (e.g. with some code in ~/.bashrc or ~/.profile), so that any processes started from within that newly opened shell will inherit the assignments via environmental variables.
The obvious solution would be to prefix each line in site.conf with an export and just source the file. However I cannot do this since the file is also read (directly) by some other applications, so the format is fixed.
I tried something like
cat site.conf | while read assignment
do
export "${assignment}"
done
But this doesn't work, for various reasons (the most important being that export is executed in a subshell, so the variable will never be exported to the children of the calling shell).
Is there a way to programmatically export unknown variables in bash?
Run set -a before sourcing the file. This marks all new and modified variables that follow for export automatically.
set -a
source site.conf
set +a # Require export again, if desired.
The problem you observed is that the pipe executes the export in a subshell. You can avoid that simply by using input redirection instead of a pipe.
while read assignment; do
export "$assignment"
done < site.conf
This won't work, however, if (unlikely though it is) you have multiple assignments on one line, such as
EMAIL="dev#example.com" FULLNAME="Master Yedi"
Let's say a script is called with /bin/sh. Is it possible to source another script from that script and to have it be interpreted with #!/bin/bash?
It would appear that the #!/bin/bash doesn't do anything...
And by source, at this point I am meaning the functionality of manipulating the parent environment.
No. The whole point of sourcing a script is that the script is interpreted by the shell doing the sourcing. If, as is often the case, /bin/sh is bash, then you will get the desired behavior. Otherwise, you are out of luck.
Try the source command, or dot operator. You might also try the env command. Note, make sure you export if you're using source (or dot).
I am new at bash and trying to solve some issues for a code I'm trying to make.
I am at the terminal under my user name and connect to bash
USER$
USER$ bash
bash$
now in the bash I am saving some variables f.e:
i=2
k=2
let p=$k*$i
now I want to use those variables outside the bash function
bash$exit
USER$
but now the variables are not there
I try using export, but it did not really work, could use ur help, tnx
Not possible. You cannot set environment variables in a parent process like this.
Unlike a DOS batch file, a Unix shell script cannot directly affect the environment of its calling shell.
You could consider using the . (dot) or source command to read and execute the script in the context of the calling shell. This means that changes made in the script do affect the environment (in general; you can still run into issues with sub-shells).
The other alternative is to have the script that sets the variables write the values in name=value format into a file which the calling script then reads (with . or source again).
The conventional solution is to add the settings to your .profile or . bashrc -- which you should use depends on your specific needs and your local Bash configuration; my first recommendation would be .profile, but then you have to avoid any bashisms because this file is shared with sh (so, no let, for example).
For more specific needs, put the commands in a file, and source it when you need it. You might also want to create a simple script to update the file with your current values.
# source this file to update $HOME/stuff
cat<<HERE>$HOME/stuff
i='$i'
k='$k'
p='$p'
export i k p
HERE
The syntax here is quite simple, but assumes you don't have values which can contain single quotes or otherwise free-form content. How to safely store arbitrary values which you don't have complete control over is a much more complex discussion; I am providing a simple solution for the basic use case where you merely need to save a few simple scalar values, like numbers.
To keep your variables when you connect to a remote system, look at the documentation for the tool you are using to connect. For example, ssh has configuration options for importing environment variables from the local system when starting a remote session.
I'm trying to add some export statements in my Unix shell script and up to this point I've only gotten it to work with the bash shell. Is there a way to make the below export apply in all shells using shell scripting?
AXIS2_HOME=/home/user/axis2-1.6.0
export AXIS2_HOME
What do you mean "all shells?"
If you mean different shells as in "can I change my parent/sibling shell's environment"?
Then no, you can't. Exporting a var should mean all your children inherit it though.
You can go some way to faking it by having your script create a temp file that you somehow get the caller to execute, but it's starting to get a biut weird and suggests a problem in your architecture.
If you mean different shells as in sh/bash/csh/tcsh/zsh/ksh etc
You can make something like that work in all "sh" flavour shells, but for "csh" flavours you need to use setenv.
Depending how far you want to go, you could write something to store all your env. vars in a separate file (e.g. env.dat) and convert that to sh/csh syntax using sed/awk/perl.
I have some proxy settings that I only occasionally want to turn on, so I don't want to put them in my ~/.bash_profile. I tried putting them directly in ~/bin/set_proxy_env.sh, adding ~/bin to my PATH, and chmod +xing the script but though the script runs, the variables don't stick in my shell. Does anyone know how to get them to stick around for the rest of the shell session?
Use one of:
source <file>
. <file>
In the script use
export varname=value
and also execute the script with:
source set_proxy_env.sh.
The export keyword ensures the variable is marked for automatic inclusion in the environment of subsequently executed commands. Using source to execute a script starts it with the present shell instead of launching a temporary one for the script.
Did you try this:
. ~/bin/set_proxy_env.sh
Running it by itself opens a separate subshell (I think) and sets the variable there. But then the binding is lost after exiting back into your shell. The dot at the front tells it to run it within the same shell.
Also, don't forget to export the variables you need like so: export MYVAR=value