我已经设置了一个Bash菜单脚本,该脚本也需要用户输入。 这些输入被写入(附加)一个名为var.txt的文本文件,如下所示:
input[0]='192.0.0.1'
input[1]='username'
input[2]='example.com'
input[3]='/home/newuser'
现在我想要完成的是能够从类似这样的脚本中读取var.txt:
useradd var.txt/${input[1]}
现在我知道仅仅使用它作为一个例子。
先谢谢, 乔
答案 0 :(得分:14)
使用bash's readarray
statement。 (这是我可以找到动态地在数组元素中放置空格的唯一方法。)你需要你的var.txt
文件只包含数组的元素,每行一个,不包含赋值语句。
readarray -t input < var.txt
有关详细信息,请尝试help readarray
(然后会告诉您尝试help mapfile
)。
这是我对它的测试:
echo -e "a\nb c\nd" > var.txt
readarray input < var.txt
for item in "${input[@]}"; do echo $item; done
打印:
a
b c
d
注意:执行cat var.txt | readarray -t input
不起作用。我认为这是因为input
变量的范围超出了范围。
答案 1 :(得分:6)
如果整个var.txt
文件只包含您指定的与Bash兼容的变量赋值,您可能只能source,以便在新的Bash脚本中使这些变量可用:
source var.txt
useradd ${input[1]}
但是,这将覆盖任何具有相同名称的现有变量。通过选择特定变量,可以使用Command substitution来避免这种情况:
input[1]="$(grep '^input\[1\]=' var.txt | sed "s|[^=]*='\(.*\)'|\1|")"
它允许重命名变量,但您必须为每个感兴趣的变量执行此操作。它本质上从var.txt
文件中提取变量的值,并将其分配给新变量。有关其使用的详细信息,请参阅grep manual page和sed info page。
Process substitution可能允许更简单的表达式:
source <(grep '^input\[[0-9]*\]=' var.txt)
useradd ${input[1]}
这将允许您仅导入感兴趣的定义,但您必须注意不需要的变量覆盖。
答案 2 :(得分:3)
您可以将变量提取封装在函数中,并利用declare
在函数内部使用时创建局部变量的事实。每次调用函数时,此技术都会读取文件。
readvar () {
# call like this: readvar filename variable
while read -r line
do
# you could do some validation here
declare "$line"
done < "$1"
echo ${!2}
}
给定一个名为“data”的文件,其中包含:
input[0]='192.0.0.1'
input[1]='username'
input[2]='example.com'
input[3]='/home/newuser'
foo=bar
bar=baz
你可以这样做:
$ a=$(readvar data input[1])
$ echo "$a"
username
$ readvar data foo
bar
这将读取一个数组并重命名:
readarray () {
# call like this: readarray filename arrayname newname
# newname may be omitted and will default to the existing name
while read -r line
do
declare "$line"
done < "$1"
local d=$(declare -p $2)
echo ${d/#declare -a $2/declare -a ${3:-$2}};
}
示例:
$ eval $(readarray data input output)
$ echo ${output[2]}
example.com
$ echo ${output[0]}
192.0.0.1
$ eval $(readarray data input)
$ echo ${input[3]}
/home/newuser
这样做,您只需要对该函数进行一次调用,整个数组就可以使用,而不必进行单独的查询。