bash-скрипт для запуска второй команды с выбором выходных данных из первой команды в качестве переменной

Я хотел бы получить выходные данные второй команды с 7-символьным доменом PSI (00:01.0) в качестве переменной. Как я могу написать bash-скрипт для этого?

jeff @ jeff-probook: / $ lspci | grep VGA
    00: 01.0 VGA-совместимый контроллер: Advanced Micro Devices, Inc. [AMD/ATI] Carrizo (версия 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-контроллер])
    Подсистема: Hewlett-Packard, компания Carrizo
    Флаги: мастер шины, быстрая девсель, латентность 0, IRQ 231
    Память на c0000000 (64-битная, с возможностью предварительной выборки) [размер =256M]
    Память на d0000000 (64-битная, с возможностью предварительной выборки) [размер =8M]
    Порты ввода / вывода на 3000 [размер =256]
    Память в d0d00000 (32-разрядная, без предварительной выборки) [размер = 256 КБ]
    ПЗУ расширения на d0800000 [отключено] [размер =128 КБ]
    Возможности: 
    Используемый драйвер ядра: amdgpu
    Модули ядра: amdgpu

Это определенно не работает:

user @ host: ~ $ cat lspciVGA
#! / Bin/ Баш

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

Выход:

user @ host: ~ $ bash lspciVGA
expr: синтаксическая ошибка
lspci: опция требует аргумент - 's'
Использование: lspci []

Основные режимы отображения:
-mm Создать машинно-читаемый вывод (одиночный -m для устаревшего формата)
-t Показать автобусное дерево

Показать варианты:
-v быть многословным (-vv для очень многословного)
-k Показать драйверы ядра, обрабатывающие каждое устройство
-x Показать шестнадцатеричный дамп стандартной части пространства конфигурации
-xxx Показывать шестнадцатеричный дамп всего пространства конфигурации (опасно; только root)
-xxxx Показать шестнадцатеричный дамп расширенного пространства конфигурации 4096 байт (только root)
-b Шинно-ориентированный вид (адреса и IRQ, как видно на автобусе)
-D Всегда показывать номера доменов

Преобразование идентификаторов устройств в имена:
-n Показать числовые идентификаторы
-nn Показать текстовые и числовые идентификаторы (имена и номера)
-q Запросить базу данных PCI ID для неизвестных идентификаторов через DNS
-qq Как и выше, но повторно запросить локально кэшированные записи
-Q Запрос базы данных PCI ID для всех идентификаторов через DNS

Подбор устройств:
-s [[[[]:]]:][][.[]] Показать только устройства в выбранных слотах
-d []:[] Показать только устройства с указанными идентификаторами

Другие опции:
-i Использовать указанную базу данных идентификаторов вместо /usr/share/misc/pci.ids.gz
-p Искать модули ядра в заданном файле вместо модулей по умолчанию.pcimap
-M Включить режим `bus mapping'(опасно; только 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

2 ответа

Решение

Есть проблема в назначении var2. Следует читать:

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

причина кавычек в том, что в var1 есть пробелы, которые запутывают 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"

С помощью 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
Другие вопросы по тегам