繁体   English   中英

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

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

许多 shell 脚本,包括 bash 配置文件,只是环境变量设置的列表。 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/"

VERSION_CODENAME对于添加到 apt 源 ( /etc/apt/sources.list ) 尤其有用,例如Steam 在 ChromeOS 上工作 请注意,大多数指令都会硬编码此值,这可能会导致兼容性问题。

所以我的问题是如何在使用source的情况下从/etc/os-release之类的文件中echo显诸如VERSION_CODENAME之类的环境变量? 这很关键,因为我不想一次性使用这些环境变量来混淆我的环境变量。

这是我知道我现在可以做的,但它在我当前的环境中留下了不受欢迎的变量:

source /etc/os-release && echo "deb http://httpredir.debian.org/debian/ $VERSION_CODENAME main contrib non-free | sudo tee -a /etc/apt/sources.list"

我想也许有一种方法可以启动一个新的(临时)bash 进程并将变量加载到该环境中。 如果没有实际的 shell 脚本,我无法弄清楚这一点。

这里有4个不同的答案...

对不起,但方法不止一种;)。 您可能会找到很多其他方法,但有最合适的(快速、高效、占用空间、可读性......)。

1. 通过sed导入以填充关联数组

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

然后

echo ${IMPORTED[VERSION_CODENAME]}
buster

2.提取必填字段(再次使用sed

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

3.括号下拉到subshell使用他自己的环境

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

echo $VERSION_CODENAME
 

当前环境不知道$VERSION_CODENAME

4.在纯bash中读取变量文件,没有fork

由于我们正在处理一个小文件,我们可以使用循环来读取文件,直到找到所需的信息:

while IFS== read varname value;do
    [ "$varname" = "VERSION_CODENAME" ] &&
        ImportedVersionCodename=$value && break
done </etc/os-release
echo $ImportedVersionCodename 
buster

我想也许有一种方法可以启动一个新的(临时)bash 进程并将变量加载到该环境中。

这就是使用括号创建子外壳的作用。

(
  . /etc/os-release
  echo "deb http://httpredir.debian.org/debian/ $VERSION_CODENAME main contrib non-free" \
  | sudo tee -a /etc/apt/sources.list
)

...一旦)被击中,您的变量就会被删除,因为它们被加载到退出的子shell中。

或者像这样使用readprintf

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

下一个 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.."

当您不需要环境中的 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