sch*_*ity 5 grep bash usb variable lsblk
我有一个脚本,我想在其中使用命令列出 USB 设备lsblk
。
命令:
$ lsblk -o NAME,TRAN,VENDOR,MODEL | grep usb
Run Code Online (Sandbox Code Playgroud)
这导致
sdb usb Kingston DataTraveler 2.0
sdc usb Kingston DT 101 G2
Run Code Online (Sandbox Code Playgroud)
我想将结果保存在一个变量中以便以后工作,所以我写
$ usbs=$(lsblk -o NAME,TRAN,VENDOR,MODEL | grep usb)
Run Code Online (Sandbox Code Playgroud)
我期待的是变量usbs
将结果存储在两整行中,如上所示。但如果我跑:
for i in ${usbs[@]}; do
echo $i
done
Run Code Online (Sandbox Code Playgroud)
我把结果分成几个词:
sdb
usb
Kingston
DataTraveler
2.0
sdc
usb
Kingston
DT
101
G2
Run Code Online (Sandbox Code Playgroud)
问题:
有没有办法,使用grep
命令,我可以将命令的结果存储为两整行?
我更愿意知道是否有一个简单的解决方案,而不是将结果转储到文件中然后读取它。
jes*_*e_b 10
这是使用readarray/mapfile的好情况:
readarray -t usbs < <(lsblk -o NAME,TRAN,VENDOR,MODEL | grep usb)
Run Code Online (Sandbox Code Playgroud)
这将使用您的输出创建一个数组,其中每一行都被分成它自己的元素。
在您的情况下,它会生成一个数组,如:
usbs=(
'sdb usb Kingston DataTraveler 2.0'
'sdc usb Kingston DT 101 G2'
)
Run Code Online (Sandbox Code Playgroud)
就像您将整个输出分配给一个变量(而不是数组)一样,它本质上是这样做的:
usbs='sdb usb Kingston DataTraveler 2.0
sdc usb Kingston DT 101 G2 '
Run Code Online (Sandbox Code Playgroud)
为了使它成为一个数组,您将执行以下操作:
usbs=($(lsblk -o NAME,TRAN,VENDOR,MODEL | grep usb))
Run Code Online (Sandbox Code Playgroud)
但这会使每个由空格分隔的单词成为它自己的元素,相当于:
usbs=(
sdb
usb
Kingston
DataTraveler
2.0
sdc
usb
Kingston
DT
101
G2
)
Run Code Online (Sandbox Code Playgroud)
正如一些评论者所指出的那样,并且通常始终是最佳实践,应该引用变量。在这种情况下,您必须并且通常始终应该引用您的变量。
首先,我想说这不是解决问题的正确方法。这有点像说“你不应该杀人,否则你会进监狱”。
同样,您不引用您的变量,因为否则您将引入安全漏洞。你引用你的变量是因为不引用是错误的(但如果对监狱的恐惧可以提供帮助,为什么不呢)。
- 斯蒂芬·查泽拉斯
在 的情况下for i in ${usbs[@]}; do
,i
将设置为 中的每个单词(由空格分隔)usbs
。如果你引用它喜欢for i in "${usbs[@]}"; do
,那么i
将被设置为每一个元素的usbs
作为需要。
问题:有没有一种方法可以使用
grep
命令将命令结果存储为两整行?
是的,您的分配代码是正确的:
Run Code Online (Sandbox Code Playgroud)usbs=$(lsblk -o NAME,TRAN,VENDOR,MODEL | grep usb)
这完全符合要求;在单个变量(不是数组)中,它存储由lsblk
换行符分隔的两行。但for
循环并不是读取该变量的正确工具。循环while
要好得多,下面是一个带有虚构数据的示例,因为某些读者可能没有插入任何 USB 设备:
t=$(echo foo bar; echo baz bing;)
while read i ; do echo "$i" ; done <<< "$t"
Run Code Online (Sandbox Code Playgroud)
输出:
foo bar
baz bing
Run Code Online (Sandbox Code Playgroud)
这是一个更短的方法:
xargs -L 1 <<< "$t"
Run Code Online (Sandbox Code Playgroud)
注意:虽然普通POSIX样式变量x
不是数组,但bash
允许x
使用数组表示法进行标识,并且不会抱怨x
不是数组。演示:
x=f
echo $x ${x[0]} ${x[@]}
Run Code Online (Sandbox Code Playgroud)
输出:
f f f
Run Code Online (Sandbox Code Playgroud)
但x
不是数组。如果是的话,这段代码(使用bash
参数转换 赋值运算符)肯定会输出一个数组:A
echo "${x[@]@A}"
Run Code Online (Sandbox Code Playgroud)
...它没有:
x='f'
Run Code Online (Sandbox Code Playgroud)
为了对比,让我们将上面的内容与它是一个数组时的样子进行比较。首先创建一个非常相似的数组y
,然后使用赋值运算符来显示差异:A
y=(f)
echo "${y[@]@A}"
Run Code Online (Sandbox Code Playgroud)
输出:
declare -a y=([0]="f")
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2005 次 |
最近记录: |