[英]Bash - assign variables to output of a command in a loop
I've got an application that runs and defines the devices on a system. 我有一个运行并定义系统上设备的应用程序。 The output looks something like this:
输出看起来像这样:
./show-devices 192.168.1.2 | grep volume
/dev/sda volumeid-65
/dev/sdb volumeid-81
/dev/sdc volumeid-92
What I'm trying to do is run the application in a loop and assign variables like so: 我想做的是在循环中运行应用程序并分配变量,如下所示:
sda=volumeid-65
sdb=volumeid-81
sdc=volumeid-92
Then, be able to use the $sda, $sdb, and $sdc variables later on in the script. 然后,稍后可以在脚本中使用$ sda,$ sdb和$ sdc变量。 Not all outputs are the same.
并非所有输出都相同。 Some machines will only have one volume, some will have more.
有些机器只有一个音量,有些则更大。 All suggestions are welcome.
欢迎所有建议。 I've tried many combinations of a for loop and don't appear to be getting anywhere.
我已经尝试了for循环的许多组合,但似乎并没有取得进展。 Thank you!
谢谢!
How about: 怎么样:
eval `./show-devices 192.168.1.2 | grep volume | while read d v ;do
echo $(basename $d)=$v
done`
However, you'll not be sure of the names of the variables. 但是,您将不确定变量的名称。 So it's better to use an associative array:
因此,最好使用关联数组:
# declare the array
declare -A volumes
# Assign values to the array
eval `./show-devices 192.168.1.2 | grep volume | while read d v ;do
echo volumes[$(basename $d)]=$v
done`
# Use the array
for i in "${!volumes[@]}"; do
echo "Key:$i , Value:${volumes[$i]}"
# Declare all the variables with the values as asked by question
eval $i=${volumes[$i]}
done
Explaination : | while read dv
释 :
| while read dv
| while read dv
loops over the output of the previous command reading 2 values per line. | while read dv
循环遍历前一个命令的输出,每行读取2个值。 basename $d
gives me the base name of the device and $v contains the volume associated with the device. basename $d
给我设备的基本名称,$ v包含与设备关联的卷。 This is assigned into the volumes
associative array declared with declare -A volumes
. 这被分配给用
declare -A volumes
声明的volumes
关联数组。 The while
loop runs ins a sub-shell and prints volumes[sda]=...
and eval
evaluates this in the current shell, actually assigning the value. while
循环在子外壳程序中运行并打印volumes[sda]=...
而eval
在当前外壳程序中对此进行评估,实际上是在分配值。
Usage : The for
loop is a usage example. 用法 :
for
循环是一个用法示例。 "${!volumes[@]}"
is the list of keys for the volumes
array, and the for
loop loops over them and prints the value associated with each key in the volumes
array. "${!volumes[@]}"
是volumes
数组的键列表,并且for
循环在它们上循环并打印与volumes
数组中的每个键关联的值。
Edits : 编辑 :
Modified the while
loop to echo the assigment and eval
the whole thing (to get around the subshell being spawned by the pipe. 修改了
while
循环,以呼应分配并eval
整个事情(以避开由管道生成的子外壳。
Added usage info 添加了用法信息
Added exact solution asked in question 添加了有问题的确切解决方案
source <(
./show-devices 192.168.1.2 |
sed -rn '/volume/{s#/dev/([^[:space:]]+)[[:space:]]+#\1=#;p}'
)
This runs your command, passes it through sed to format it like shell assignments, and then uses a process substitution to treat the output like a file which is sourced into the current shell. 这将运行您的命令,将其传递给sed以将其格式化为类似于外壳分配的格式,然后使用进程替换将输出像将其视为源于当前外壳的文件一样对待。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.