Defining common variables across multiple scripts?
Asked Answered
D

3

7

I have a number of Bash and Perl scripts which are unrelated in functionality, but are related in that they work within the same project. The fact that they work in the same project means that I commonly specify the same directories, the same project specific commands, the same keywords at the top of every script.

Currently, this has not bitten me, but I understand that it would be easier to have all of these values in one place, then if something changes I can change a value once and have the various scripts pick up on those changes.

The question is - how is best to declare these values? A single Perl script that is 'required' in each script would require less changes to the Perl scripts, though doesn't provide a solution to the Bash script. A configuration file using a "key=value" format would perhaps be more universal, but requires each script to parse the configuration and has the potential to introduce issues. Is there a better alternative? Using environmental variables? Or a Bash specific way that Perl can easily execute and interpret?

Decrepitude answered 1/12, 2014 at 10:45 Comment(5)
A key=value format is native sh and can be sourced with the . command. It can be easily parsed with perl.Californium
Oh well done, very true! I feel most stupid now.Decrepitude
You can also create global environment variables using export command. For example: export FOO=2.Plossl
Another thought: put your data in a shell script. That script would take an option that controls how the data is output. The calling program would eval the results. ssh-agent does this: eval ssh-agent -c for c-shell, eval ssh-agent -s for bourne shell.Californium
For this, we've used a 'source' file - which you can either source before running perl, or inline . SOURCE; echo \$varClothespin
P
7

When you run a shell script, it's done in a sub-shell so it cannot affect the parent shell's environment. So when you declare a variable as key=value its scope is limited to the sub-shell context. You want to source the script by doing:

. ./myscript.sh

This executes it in the context of the current shell, not as a sub shell.

From the bash man page:

. filename [arguments]
source filename [arguments]

Read and execute commands from filename in the current shell environment and return the exit status of the last command executed from filename.

If filename does not contain a slash, file names in PATH are used to find the directory containing filename. 

Also you can use the export command to create a global environment variable. export governs which variables will be available to new processes, so if you say

FOO=1
export BAR=2
./myscript2.sh

then $BAR will be available in the environment of myscript2.sh, but $FOO will not.

Plossl answered 1/12, 2014 at 11:15 Comment(1)
This is the route I have taken, then in Perl used my %CONFIG = read_file( "path/to/config" ) =~ /^(.+)=(.*)$/mg; in order to parse and use the variables within.Decrepitude
M
2

Define environments variables : user level : in your ~/.profile or ~/.bash_profile or ~/.bash_login or ~/.bashrc system level : in /etc/profile or /etc/bash.bashrc or /etc/environment

For example add tow lines foreach variable :

FOO=myvalue
export FOO 

To read this variable in bash script :

#! /bin/bash

echo $FOO

in perl script :

#! /bin/perl

print $ENV{'FOO'};
Menorca answered 1/12, 2014 at 11:20 Comment(1)
Although this would work, I think that reducing the number of environmental variables is probably A Good Thing, certainly then no other processes can alter them as easily.Decrepitude
L
0

You could also source another file, so you do not create extra env variables, that may lead to unexpected behaviours.

source_of_truth.sh:

FOO="bar"

scritp1.sh

#!/usr/bin/env bash

source source_of_truth.sh

echo ${FOO}
# ... doing something

scritp2.sh

#!/usr/bin/env bash

source source_of_truth.sh

echo ${FOO}
# ... doing something else
Laurustinus answered 22/9, 2021 at 22:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.