how can I turn config ini file into system environment in bash? - bash

I have config files like below
# this is sample config file like config.ini
APP_HOME=/usr/local/bin
DATABASE_DIR=/usr/local/database
Normally in order to be access as system environment, it shall use export in front
# this is sample config file like config.rc
export APP_HOME=/usr/local/bin
export DATABASE_DIR=/usr/local/database
And I can
$ source config.rc
$ echo "APP_HOME is $APP_HOME"
APP_HOME is /usr/local/bin
Now Which is the easiest way one line command to turn config file config.ini into system environment ? could be combine with sed/awk command

You can tell the shell to automatically export variables, if you really do need this to be exported.
set -a # turn on automatic export
source config.ini # execute all commands in the file
set +a # turn off automatic export

sed 's/^/export /g' config.ini > config.sh && source config.sh
The sed command add 'export ' to the beginning for each line of config.ini and then redirect the output to config.sh, then the source shell builtin read and execute the exports in the current shell environment.

To export the variables in that file after you source if:
export $(grep -oP '^\s*\K[_[:alpha:]]\w+(?==)' config.ini)

one line:
cat 1.ini | awk '{print "export "$0}'

Related

Bash: export .env variables [duplicate]

Let's say I have .env file contains lines like below:
USERNAME=ABC
PASSWORD=PASS
Unlike the normal ones have export prefix so I cannot source the file directly.
What's the easiest way to create a shell script that loads content from .env file and set them as environment variables?
If your lines are valid, trusted shell but for the export command
This requires appropriate shell quoting. It's thus appropriate if you would have a line like foo='bar baz', but not if that same line would be written foo=bar baz
set -a # automatically export all variables
source .env
set +a
If your lines are not valid shell
The below reads key/value pairs, and does not expect or honor shell quoting.
while IFS== read -r key value; do
printf -v "$key" %s "$value" && export "$key"
done <.env
This will export everything in .env:
export $(xargs <.env)
Edit: this requires the environment values to not have whitespace. If this does not match your use case you can use the solution provided by Charles
Edit2: I recommend adding a function to your profile for this in any case so that you don't have to remember the details of set -a or how xargs works.
This is what I use:
function load_dotenv(){
# https://stackoverflow.com/a/66118031/134904
source <(cat $1 | sed -e '/^#/d;/^\s*$/d' -e "s/'/'\\\''/g" -e "s/=\(.*\)/='\1'/g")
}
set -a
[ -f "test.env" ] && load_dotenv "test.env"
set +a
If you're using direnv, know that it already supports .env files out of the box :)
Add this to your .envrc:
[ -f "test.env" ] && dotenv "test.env"
Docs for direnv's stdlib: https://direnv.net/man/direnv-stdlib.1.html
Found this:
http://www.commandlinefu.com/commands/view/12020/export-key-value-pairs-list-as-environment-variables
while read line; do export $line; done < <(cat input)
UPDATE So I've got it working as below:
#!/bin/sh
while read line; do export $line; done < .env
use command below on ubuntu
$ export $(cat .env)

Jenkins can't access shell alias

I have configured a Jenkins job to source a bash script that sources another bash script which adds an alias to the .bashrc of its user and sources the .bashrc itself, and then original script tries to use that alias (set by the second). However, it cannot seem to find the alias it has just created. I am not using any scripting plugins aside from using a "Send files or execute commands over SSH" build step to source the script.
The job does this:
source ./test_script.sh
test_script.sh looks like this:
echo "In test_script.sh"
echo $USER
echo $HOME
source ./setup_env.sh
echo "\nBack in test_script.sh"
alias foo
foo
And finally, setup_env.sh looks like this:
echo "\nIn setup_env.sh"
echo "alias foo=\"echo foobar\"" >> $HOME/.bashrc
source $HOME/.bashrc 2>/dev/null
cat $HOME/.bashrc
The output I receive from the Jenkins job looks like this:
In test_script.sh
my_user
/home/my_user
\nIn setup_env.sh
...all of my bashrc...
alias foo="echo foo"
\nBack in test_script.sh
alias foo='echo foo'
./test_script.sh: line 7: foo: command not found
I don't understand why this is happening, when I can happily run it myself on the command-line and watch it succeed. Why can't Jenkins use the new alias, when it can obviously find it (as demonstrated by the output of the alias foo command)?
For anyone else who's having this problem, you may need to set the expand_aliases shell option, which seems to be off by default with Jenkins:
shopt expand_aliases # check if it's on
shopt -s expand_aliases # set expand_aliases option to true
shopt expand_aliases # it should be on now
# test with a simple alias, should print 1
alias x="python -c 'print 1'"
x
The \n that is showing in the output of your echo commands
suggest this is not running under bash, as you may be expecting.
Please check the setting of your jenkins user
(or any other user that you run Jenkins with) -
especially the setting of the default shell.
To test this, add one of those lines at the beginning of your script:
env
or
env | grep -i shell
Should also consider making sure your scripts run under the correct shell,
by adding the "shebang" line as the first line in each script.
In the case of 'bash', for example, you should add the following first line:
#!/bin/bash
(it is not a comment, despite what the auto-syntax-highlighter may think...)

Pipe to export command

Why does export fail when used as the last step in a command pipeline?
echo FOO=bar | xargs export
# => xargs: export: No such file or directory
I can rewrite it this way to accomplish what I want:
export `echo FOO=bar`
But why can't I use export in the first way?
export is a shell builtin and xargs expects an actual binary.

Shell: read a file and echo it's contents to another file

I have a Makefile that is supposed to echo aliases from another file to your local .zshrc file.
I need to read the contents of the file aliases.sh, and echo it's contents to ~/.zshrc, how is this possible?
cat aliases.sh >> ~/.zshrc

Use a grepped file as an included source in bash

I'm on a shared webhost where I don't have permission to edit the global bash configuration file at /ect/bashrc. Unfortunately there is one line in the global file, mesg y, which puts the terminal in tty mode and makes scp and similar commands unavailable. My local ~./bashrc includes the global file as a source, like so:
# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
My current workaround uses grep to output the global file, sans offending line, into a local file and use that as a source.
# Source global definitions
if [ -f /etc/bashrc ]; then
grep -v mesg /etc/bashrc > ~/.bash_global
. ~/.bash_global
fi
Is there a way to do include a grepped file like this without the intermediate step of creating an actual file? Something like this?
. grep -v mesg /etc/bashrc > ~/.bash_global
lose the cat, its useless
source <(grep -v "mesg" /etc/bashrc)
the <() syntax is called process substitution.
. <(grep -v mesg /etc/bashrc)
I suggest to call mesg n :)
From memory, but something like
grep -v mesg /etc/bashrc | eval
should do the trick
Since i'm not sure eval will read stdin, you may need to rephrase it into
eval `grep -v mesg /etc/bashrc`

Resources