设置一个变量,其值取决于另一个变量

设置一个变量,其值取决于另一个变量

我有一个文本文件变量.txt我存储变量的地方

主机=/srv/www/vhosts/hosting

索引=$主机/index.php

如您所见,第二个变量取决于第一个变量。

我还有一个脚本文件来加载这些变量

f=~/variables.txt
for line in $(cat $f)
do
export $line
done

当我执行脚本文件时,我的第一个变量被加载,而第二个变量则没有:

bash: $host/index.php: No such file or directory

这是因为加载第一个变量后主持人,它不记得用于设置第二个变量的值指数

那么如何解决这个问题呢?我想应该有一些额外的选项或参数来传递,以使其(export?)记住循环中设置的变量值for

答案1

首先要注意的是,您可能不需要导出这些变量;保留必要性仅有的当子进程查询其继承环境中的变量时。最常见的是,人们导出一个变量,然后执行类似的操作somecmd "$myexportedvar"。你的外壳在看到它$myexportedvar之前就已经膨胀了。somecmd

如果您确实需要导出这些子进程以从其环境中提取:

while IFS= read -r line; do
  if [[ $line == *=* && $line != #* ]]; then
    IFS== read -r var val <<<"$line"
    printf -v "$var" '%s' "$val"
    export "$var"
  fi
done < "$HOME/variables.txt"

这个循环检查该行是否是一个赋值(有点)并且第一个字符不是注释哈希。使努力变得更加有力,但也只是勉强。请参阅下面的两个选项,以更仔细地处理此问题。

顺便说一句,上面的循环将确保你不会执行解析出的文件。source评估每一行并实际执行它们,因此我的循环将消除该“问题”(如果您认为这是一个问题)。

或者,只需导出原始文件中的变量,然后source "$HOME/variables.txt"工作就已经完成了。

你可能只想使用set -a; . "$HOME"/variables.txt; set +a.这可以避免源文件不包含的问题独自的作业。上面的解析循环可能会导致误报。阅读help set以了解它在做什么。

还,不要读取带有 For 的行使用更多报价

答案2

您有更简单的方法来执行此操作。

cat vars
host=/srv/www/vhosts/hosting
index=$host/index.php

我的测试脚本:

#!/bin/bash
. ./vars
echo $host
echo $index

执行

./printvars.sh
/srv/www/vhosts/hosting
/srv/www/vhosts/hosting/index.php

基本上是 . ./vars 执行文件并加载变量。

答案3

我的建议也是获取该文件并导出“variables.txt”文件中的所有内容。现代文本编辑器应该允许“列编辑”,或者您可以编写修改脚本。

但是,我设法用这个脚本回答你的问题:

#!/bin/sh

f=./variables.txt
source ${f}
for vname in $(cut -f1 -d'=' ${f})
do
    export ${vname}
done

不同之处在于,我首先获取 Variables.txt 文件,以便所有变量都在此 shell 的范围内定义并具有正确的解释。只有这样我才能通过仅获取变量的名称(vname)来导出文件的所有变量。

附带说明一下,您应该使用 ${} 保护您的变量。

答案4

您可以分两步完成:

. ./vars
while read line; do
    export $(printf "%s" "$line" | grep = | cut -d= -f 1)
done < vars

或者只是一个

while read line; do
   eval export "$line"
done < vars

相关内容