bash - 来自源文件的 Bash 循环动态变量
问题描述
我有一个名为的配置文件user.conf
,其中包含此列表:
USER1_USERNAME="John"
#USER2_USERNAME="Mike"
USER3_USERNAME="David"
USER4_USERNAME="James"
USER5_USERNAME="Jenny"
请注意,用户可以注释掉该行USER2_USERNAME
,因此 bash 脚本的源文件中只使用了 4 个用户test.sh
:
#!/bin/bash
#source the username
source "user.conf"
n=1
while :; do
((n++))
if [ -n "${USER${n}_USERNAME}"]; then
echo "This variable USER${n}_USERNAME is set: ${USER${n}_USERNAME}"
else
echo "This variable USER${n}_USERNAME is not set"
fi
done
我想显示哪个变量设置了它的值并跳过注释变量,但此时我的代码只显示一个错误:
./test.sh: line 8: ${USER${n}_USERNAME}: bad substitution
是否可以像上面那样循环该变量?
USER
此外,用户可以在其中定义更多user.conf
,例如
USER6_USERNAME="George "
预期输出:
This variable USER1_USERNAME is set to John
This variable USER2_USERNAME is not set
This variable USER3_USERNAME is set to David
This variable USER4_USERNAME is set to James
This variable USER5_USERNAME is set to Jenny
解决方案
您可以像这样使用 bash 变量替换:
#!/usr/bin/env bash
source "user.conf"
for i in "${!USER@}"
do
echo $i ${!i}
done
像您的代码一样,这首先获取用户文件,因为它看起来像一个 bash 脚本。这当然有潜在危险的副作用,user.conf 中的任何其他代码也会运行,所以要小心,不要让陌生人修改该文件。
然后它使用${!var@}
,它扩展为名称以前缀开头的变量的名称,此处为“var”,或者为您提供“USER”。您也可以使用${!var*}
,这取决于您是想要一个引用变量还是多个变量中的所有值。有关详细信息,请参阅shell 参数扩展。
整个方法与配置变量的公共前缀相关联。在这种情况下,您还将$USER
在输出中看到当前登录用户的名称。您可以使用例如grep
或简单if [ "$i" != "USER" ]
的循环过滤它。
如果您还想要未定义的变量,则获取用户文件可能不是一个好的解决方案。您可以改为逐行读取文件并检查前导#
:
#!/usr/bin/env bash
set -eu
while IFS= read -r line
do
var=$(echo "$line" | cut -d '=' -f 1)
name=$(echo "$line" | cut -d '=' -f 2)
if [[ "$var" =~ ^# ]]
then
var=$(echo "$var" | cut -c 2-)
echo "The variable $var is not set"
else
echo "The variable $var is set to $name"
fi
done
输出:
bash users.sh < users.conf
The variable USER1_USERNAME is set to "John"
The variable USER2_USERNAME is not set
The variable USER3_USERNAME is set to "David"
The variable USER4_USERNAME is set to "James"
The variable USER5_USERNAME is set to "Jenny"
但是,这种方法很脆弱,因为它不理解 bash 语法。采购时可以使用前导空格,但会触发此代码的注释检测。用户名中的变量不会被扩展,这可能是也可能不是一件好事。
推荐阅读
- c# - 是否有快速的方法或软件来查看 C# Window Form 事件的触发顺序?
- tensorflow - 如何在没有权重和偏差的情况下将预训练模型加载到 Keras 中?
- ajax - 从 Ajax 返回布尔值
- python - 我有一个包含字符串和浮点数的列表,如何按降序对数字进行排序并将列表打印到标准输出
- python - Python正则表达式从字符串中提取数字
- c# - ispostback 上 Gridview 中的标头 DDL
- android - 无法运行可以在 Android 应用程序中运行汇编代码的示例代码
- c# - 使用asp.net c#获取带有alt键代码符号的网页源代码
- html - HTML - check if content will fit into fix-sized div
- powershell - 如何获取 azure function app 凭据?