bash 脚本运行第二个命令并选择第一个命令的输出作为变量

bash 脚本运行第二个命令并选择第一个命令的输出作为变量

我想获取第二个命令的输出,其中 7 个字符的 PSI 域 (00:01.0) 作为变量。我该如何编写 bash 脚本来执行此操作?

jeff@jeff-probook:/$ lspci |删除 VGA
    00:01.0 VGA 兼容控制器:Advanced Micro Devices, Inc. [AMD/ATI] Carrizo (rev c5)
jeff@jeff-probook:/$ lspci -v -s 00:01.0
00:01.0 VGA 兼容控制器:Advanced Micro Devices, Inc. [AMD/ATI] Carrizo(rev c5)(prog-if 00 [VGA 控制器])
    子系统:惠普公司 Carrizo
    标志:总线主控、快速设备、延迟 0、IRQ 231
    内存位于 c0000000 (64 位,可预取) [size=256M]
    d0000000 处的内存(64 位,可预取)[大小=8M]
    3000 个 I/O 端口 [size=256]
    内存位于 d0d00000(32 位,不可预取)[大小=256K]
    扩展 ROM 位于 d0800000 [已禁用] [大小=128K]
    功能:
    正在使用的内核驱动程序:amdgpu
    内核模块:amdgpu

这肯定是行不通的:

用户@主机:~$ cat lspciVGA
/bin/bash #!/bin/bash

var1="$(lspci | grep -E "VGA|3D")"
var2="$(expr substr ${var1} 0 7)"
var3="$(sudo lspci -v -s ${var2})"
回显“$var3”

输出:

用户@主机:~$ bash lspciVGA
expr:语法错误
lspci:选项需要一个参数——‘s’
用法:lspci []

基本显示模式:
-mm 生成机器可读的输出(单个 -m 表示过时的格式)
-t 显示总线树

显示选项:
-v 详细(-vv 表示非常详细)
-k 显示处理每个设备的内核驱动程序
-x 显示配置空间标准部分的十六进制转储
-xxx 显示整个配置空间的十六进制转储(危险;仅限 root 用户)
-xxxx 显示 4096 字节扩展配置空间的十六进制转储(仅限 root)
-b 以总线为中心的视图(总线所见的地址和 IRQ)
-D 总是显示域名号码

将设备 ID 解析为名称:
-n 显示数字 ID
-nn 显示文本和数字 ID(名称和数字)
-q 通过 DNS 查询 PCI ID 数据库中的未知 ID
-qq 同上,但重新查询本地缓存的条目
-Q 通过 DNS 查询 PCI ID 数据库中的所有 ID

设备的选择:
-s [[[[]:]]:][][.[]] 仅显示选定插槽中的设备
-d []:[] 仅显示具有指定 ID 的设备

其他选择:
-i 使用指定的 ID 数据库而不是 /usr/share/misc/pci.ids.gz
-p 在给定文件中查找内核模块而不是默认的模块.pcimap
-M 启用“总线映射”模式(危险;仅限 root 用户)

PCI 访问选项:
-A 使用指定的 PCI 访问方法(请参阅“-A help”获取列表)
-O = 设置 PCI 访问参数(查看“-O help”获取列表)
-G 启用 PCI 访问调试
-H 使用直接硬件访问(= 1 或 2)
-F 从给定文件读取 PCI 配置转储

参考:https://stackoverflow.com/questions/8928224/trying-to-retrieve-first-5-characters-from-string-in-bash-error

答案1

var2 的赋值有问题。应为:

var2=$(expr substr "${var1}" 1 7)

之所以引用这些话,是因为变量1有空格使 substr 感到困惑,而 0 -> 1 是因为它从 1 开始计数。

您的引述也存在一些问题:

#!/bin/bash

var1=$(lspci | grep -E "VGA|3D")
var2=$(expr substr "${var1}" 1 7)
var3=$(sudo lspci -v -s "${var2}")
echo "$var3"

答案2

grep与 PCRE 一起使用( -P):

lspci | grep -Po '^\s*\K\S+(?=\s+VGA\s)'

lspci -v -s 00:01.0 | grep -Po '^\s*\K\S+(?=\s+VGA\s)'
  • ^\s*在开头匹配零个或多个空格并\K丢弃匹配,这是为了解决开头有空格的第二种情况

  • \S+匹配任意数量的非空白字符,这是我们想要的部分

  • 零宽度正向前瞻模式(?=\s+VGA\s)确保所需匹配项在VGA所需部分后的空格后溢出。


要将输出保存在变量中,请使用命令替换 ( $()):

value=$(lspci | grep -Po '^\s*\K\S+(?=\s+VGA\s)')

相似地:

value=$(lspci -v -s 00:01.0 | grep -Po '^\s*\K\S+(?=\s+VGA\s)')

现在您可以通过 获取值$value


示例(在我的系统上):

$ lspci | grep -Po '^\s*\K\S+(?=\s+VGA\s)'
00:02.0

$ lspci -v -s 00:02.0 | grep -Po '^\s*\K\S+(?=\s+VGA\s)'
00:02.0

相关内容