Я помогаю сетевому администратору с помощью регулярного выражения Perl для автоматизации работы с некоторыми снимками из нашей SAN, и наши скрипты делают что-то вроде этого:
varinit1=$(iscsiadm -m session | grep rbmsdata1 | head -n1 | perl -pe 's/^tcp: \[\d*\] \d*\.\d*\.\d*\.\d*:\d*,\d* (iqn\..*\..*\..*:.*-.*-.*-.*-(.*-.*-\d{4}-\d{2}-\d{2}-\d{2}:\d{2}:\d{2}\.\d*\.\d*))$/$1/')
varsnap1=$(iscsiadm -m session | grep rbmsdata1 | head -n1 | perl -pe 's/^tcp: \[\d*\] \d*\.\d*\.\d*\.\d*:\d*,\d* (iqn\..*\..*\..*:.*-.*-.*-.*-(.*-.*-\d{4}-\d{2}-\d{2}-\d{2}:\d{2}:\d{2}\.\d*\.\d*))$/$2/')
В сигнатуре снимка есть две части, одна вложена в другую, и мы используем группы захвата для захвата имени и части имени для различных последующих команд, которые необходимо выполнить. Я знаю, что это запуск одной и той же команды снова и снова, и регулярное выражение можно очистить позже, но в основном они используют perl для вывода одной скобки и другой.
tcp: [32] 40.40.40.101:3260,1 iqn.2001-05.com.equallogic:4-52aed6-91c5ffa78-2f0d8ae18504fee1-r12prd-rbmsdata1-2012-06-29-16:07:40.108.1
tcp: [33] 40.40.40.101:3260,1 iqn.2001-05.com.equallogic:4-52aed6-91c5ffa78-2f0d8ae18504fee1-r12prd-rbmsdata1-2012-06-29-16:07:40.108.1
Желая извлечь из того, что было результатом icsiadm и grep, получить это:
iqn.2001-05.com.equallogic:4-52aed6-91c5ffa78-2f0d8ae18504fee1-r12prd-rbmsdata1-2012-06-29-16:07:40.108.1
и
r12prd-rbmsdata1-2012-06-29-16:07:40.108.1
Проблема, с которой мы сталкиваемся, заключается в том, что иногда не удается передать первую строку по следующим причинам:
head: cannot open '–n1' for reading: No such file or directory
Конечно, это, по-видимому, указывает на то, что стандартный поток ввода head пуст, поэтому выполняется поиск имени файла.
Но нет никаких причин, по которым он когда-либо будет пустовать.
Если мы сделаем что-то вроде этого:
varinit1=$(iscsiadm -m session | grep rbmsdata1 | head -n1)
varsnap1=$(iscsiadm -m session | grep rbmsdata1 | head -n1)
второй вызовет ошибку, и вторая переменная будет пустой.
Однако если мы поменяем их местами, то varsnap1 завершится ошибкой:
varsnap1=$(iscsiadm -m session | grep rbmsdata1 | head -n1)
varinit1=$(iscsiadm -m session | grep rbmsdata1 | head -n1)
Это очень странно, и мы не можем понять, что происходит. Команда iscsiadm возвращает одно и то же при каждом запуске из командной строки и после grepping.
Что-то засорило трубопровод?
версия 5.97 на RedHat Enterprise Linux
решение1
Хотя ваш вопрос, возможно, содержит ошибку (длинное тире utf8 вместо обычного):
$ head –n1
head: cannot open ‘–n1’ for reading: No such file or directory
$ head -n1 # ctrl-d
$
Я предположу, что это просто особенность браузера, так как только один раз было похожее. head
ждет ввода, когда он ему нужен. Попробуйте заменить head -n1
на один из этих:
sed -n 1p
awk 'NR==1 {print}' # yay, no potential dash problems
Хорошо, есть еще много способов сделать это, но вы также можете пропустить этот элемент конвейера и просто указать, grep
что нужно вернуть только первое совпадение, добавив -m 1
параметр. Или исключить два элемента и указать, perl
что нужно работать только с первой совпавшей строкой.