我有一个文本文件变量.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
以了解它在做什么。
答案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