如何从 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 to work on ChromeOS。请注意,大多数指令对该值进行硬编码,这可能会导致兼容性问题。
所以我的问题是如何 echo
从文件 /etc/os-release
中 VERSION_CODENAME
的环境变量 使用 source
?这很关键,因为我不想为了一次性使用而把我的环境变量弄乱。
这是我知道我现在可以做的,但它在我当前的环境中留下了不希望的变量:
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/^\([^=]\+\)=/[]=/'))"
然后
echo ${IMPORTED[VERSION_CODENAME]}
buster
2。提取所需字段(再次使用 sed
)
AltVersionCodename=$(sed </etc/os-release -ne 's/^VERSION_CODENAME=//p')
echo $AltVersionCodename
buster
3。括号使用他自己的环境下拉到子shell
( . /etc/os-release ; echo $VERSION_CODENAME )
buster
echo $VERSION_CODENAME
当前环境不知道$VERSION_CODENAME
4。在没有 forks
的情况下以纯 bash 读取变量文件
由于我们正在处理一个小文件,我们可以使用 bash 循环读取文件,直到找到所需的信息:
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.
这就是使用括号创建子 shell 的作用。
(
. /etc/os-release
echo "deb http://httpredir.debian.org/debian/ $VERSION_CODENAME main contrib non-free" \
| sudo tee -a /etc/apt/sources.list
)
...一旦 )
被击中,您的变量将被删除,因为它们被加载到退出的子 shell 中。
或者像这样使用 read
和 printf
:
while read line; do
name=${line%%=*}
data=${line#*=}
printf -v $name "${data//\"}"
done < vars
下一个函数只获取带有键(单引号中的值)的行。
my_set() {
configfile=""
key=""
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=""
key=""
sed -n "s/^${key}=//p" "${configfile}"
}
echo "deb http://httpredir.debian.org/debian/ $(my_set2 /etc/os-release VERSION_CODENAME) main.."
许多 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 to work on ChromeOS。请注意,大多数指令对该值进行硬编码,这可能会导致兼容性问题。
所以我的问题是如何 echo
从文件 /etc/os-release
中 VERSION_CODENAME
的环境变量 使用 source
?这很关键,因为我不想为了一次性使用而把我的环境变量弄乱。
这是我知道我现在可以做的,但它在我当前的环境中留下了不希望的变量:
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/^\([^=]\+\)=/[]=/'))"
然后
echo ${IMPORTED[VERSION_CODENAME]}
buster
2。提取所需字段(再次使用 sed
)
AltVersionCodename=$(sed </etc/os-release -ne 's/^VERSION_CODENAME=//p')
echo $AltVersionCodename
buster
3。括号使用他自己的环境下拉到子shell
( . /etc/os-release ; echo $VERSION_CODENAME )
buster
echo $VERSION_CODENAME
当前环境不知道$VERSION_CODENAME
4。在没有 forks
的情况下以纯 bash 读取变量文件由于我们正在处理一个小文件,我们可以使用 bash 循环读取文件,直到找到所需的信息:
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.
这就是使用括号创建子 shell 的作用。
(
. /etc/os-release
echo "deb http://httpredir.debian.org/debian/ $VERSION_CODENAME main contrib non-free" \
| sudo tee -a /etc/apt/sources.list
)
...一旦 )
被击中,您的变量将被删除,因为它们被加载到退出的子 shell 中。
或者像这样使用 read
和 printf
:
while read line; do
name=${line%%=*}
data=${line#*=}
printf -v $name "${data//\"}"
done < vars
下一个函数只获取带有键(单引号中的值)的行。
my_set() {
configfile=""
key=""
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=""
key=""
sed -n "s/^${key}=//p" "${configfile}"
}
echo "deb http://httpredir.debian.org/debian/ $(my_set2 /etc/os-release VERSION_CODENAME) main.."