简体   繁体   English

如何从 bash 中的文件打印环境变量(不使用源)?

[英]How to print env var from file in bash (without using source)?

Many shell scripts, including the bash profile, are simply lists of environment variable settings.许多 shell 脚本,包括 bash 配置文件,只是环境变量设置的列表。 One such script on Debian is /etc/os-release which looks like this: Debian 上的一个这样的脚本是/etc/os-release ,如下所示:

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 . VERSION_CODENAME对于添加到 apt 源 ( /etc/apt/sources.list ) 尤其有用,例如Steam 在 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 ?所以我的问题是如何在使用source的情况下从/etc/os-release之类的文件中echo显诸如VERSION_CODENAME之类的环境变量? 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.我想也许有一种方法可以启动一个新的(临时)bash 进程并将变量加载到该环境中。 I haven't been able to figure that out without an actual shell script.如果没有实际的 shell 脚本,我无法弄清楚这一点。

4 different answer here...这里有4个不同的答案...

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...).您可能会找到很多其他方法,但有最合适的(快速、高效、占用空间、可读性......)。

1. import through sed to populate associative arrray : 1. 通过sed导入以填充关联数组

declare -A IMPORTED="($(sed < /etc/os-release 's/^\([^=]\+\)=/[\1]=/'))"

Then然后

echo ${IMPORTED[VERSION_CODENAME]}
buster

2. extract required field (by using sed again) 2.提取必填字段(再次使用sed

AltVersionCodename=$(sed </etc/os-release -ne 's/^VERSION_CODENAME=//p')
echo $AltVersionCodename
buster

3. parenthesis to drop down to subshell using his own environment 3.括号下拉到subshell使用他自己的环境

( . /etc/os-release ; echo $VERSION_CODENAME )
buster

echo $VERSION_CODENAME
 

Current environment don't know about $VERSION_CODENAME当前环境不知道$VERSION_CODENAME

4. reading variable file in pure bash, without forks 4.在纯bash中读取变量文件,没有fork

As we are working on a small file, we could use 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

I thought perhaps there is a way to start a new (temporary) bash process and load the variables into that environment.我想也许有一种方法可以启动一个新的(临时)bash 进程并将变量加载到该环境中。

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. ...一旦)被击中,您的变量就会被删除,因为它们被加载到退出的子shell中。

Or using read and printf like this:或者像这样使用readprintf

while read line; do
    name=${line%%=*}
    data=${line#*=}
    printf -v $name "${data//\"}"
done < vars

The next function only sources the line with the key (value in single quotes).下一个 function 仅获取带有键的行(单引号中的值)。

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当您不需要环境中的 var 时,请使用

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.."

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM