Reputation: 20344
Many shell scripts, including the bash profile, are simply lists of environment variable settings. One such script on Debian is /etc/os-release
which looks like this:
PRETTY_NAME="Debian GNU/Linux 10 (buster)"
NAME="Debian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
The VERSION_CODENAME
is particularly useful for adding to apt sources (/etc/apt/sources.list
) for, say, Steam to work on ChromeOS. Note that most instructions hard-code this value which can cause compatibility problems.
So my question then is how to echo
an env var such as VERSION_CODENAME
from a file such as /etc/os-release
without using source
? That's key because I don't want to clutter up my environment variables with these for a one-time use.
Here's what I know I can do now but it leaves the variables in my current environment which is undesirable:
source /etc/os-release && echo "deb http://httpredir.debian.org/debian/ $VERSION_CODENAME main contrib non-free | sudo tee -a /etc/apt/sources.list"
I thought perhaps there is a way to start a new (temporary) bash process and load the variables into that environment. I haven't been able to figure that out without an actual shell script.
Upvotes: 1
Views: 4142
Reputation: 71087
Sorry, but there is more than one way;). You may found a lot of other ways, but there are the most appropriate (quickness, efficience, footprint, readability...).
sed
to populate associative arrray:declare -A IMPORTED="($(sed < /etc/os-release 's/^\([^=]\+\)=/[\1]=/'))"
Then
echo ${IMPORTED[VERSION_CODENAME]}
buster
sed
again)AltVersionCodename=$(sed </etc/os-release -ne 's/^VERSION_CODENAME=//p')
echo $AltVersionCodename
buster
( . /etc/os-release ; echo $VERSION_CODENAME )
buster
echo $VERSION_CODENAME
Current environment don't know about $VERSION_CODENAME
As we are working on a small file, we could use bash loop to read the file until required info is found:
while IFS== read varname value;do
[ "$varname" = "VERSION_CODENAME" ] &&
ImportedVersionCodename=$value && break
done </etc/os-release
echo $ImportedVersionCodename
buster
Upvotes: 2
Reputation: 20032
The next function only sources the line with the key (value in single quotes).
my_set() {
configfile="$1"
key="$2"
print -v "$key" $(sed -n "s/^${key}=//p" "${configfile}")
}
my_set /etc/os-release VERSION_CODENAME
echo "deb http://httpredir.debian.org/debian/ $VERSION_CODENAME main.."
When you don't need the var in the environment, use
my_set2() {
configfile="$1"
key="$2"
sed -n "s/^${key}=//p" "${configfile}"
}
echo "deb http://httpredir.debian.org/debian/ $(my_set2 /etc/os-release VERSION_CODENAME) main.."
Upvotes: 1
Reputation: 7327
Or using read
and printf
like this:
while read line; do
name=${line%%=*}
data=${line#*=}
printf -v $name "${data//\"}"
done < vars
Upvotes: 1
Reputation: 296049
I thought perhaps there is a way to start a new (temporary) bash process and load the variables into that environment.
That's what using parenthesis to create a subshell does.
(
. /etc/os-release
echo "deb http://httpredir.debian.org/debian/ $VERSION_CODENAME main contrib non-free" \
| sudo tee -a /etc/apt/sources.list
)
...as soon as the )
is hit, your variables are removed, as the subshell they were loaded into exits.
Upvotes: 1