Comportamento peculiar do grep/head da tubulação

Comportamento peculiar do grep/head da tubulação

Estou ajudando o netadmin aqui com um regex perl para automatizar a operação em alguns instantâneos de nossa SAN e nossos scripts fazem coisas assim:

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/')

Existem duas partes na assinatura do instantâneo, uma aninhada na outra e estamos usando os grupos de captura para capturar o nome e uma parte do nome para diferentes comandos subsequentes que precisam ser executados. Eu sei que ele está executando o mesmo comando repetidamente, e o regex pode ser limpo mais tarde, mas basicamente eles estão usando perl para gerar um parênteses e o outro.

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

Querendo capturar o que foi o resultado do icsiadm e do grep para conseguir isso:

iqn.2001-05.com.equallogic:4-52aed6-91c5ffa78-2f0d8ae18504fee1-r12prd-rbmsdata1-2012-06-29-16:07:40.108.1

e

r12prd-rbmsdata1-2012-06-29-16:07:40.108.1

O problema que estamos tendo é que às vezes a tubulação para obter a primeira linha falha com:

head: cannot open '–n1' for reading: No such file or directory

Claro, isso parece indicar que o stdin head está vazio, então ele está procurando um nome de arquivo.

Mas não há razão para que esteja vazio.

Se fizermos coisas assim:

varinit1=$(iscsiadm -m session | grep rbmsdata1 | head -n1)
varsnap1=$(iscsiadm -m session | grep rbmsdata1 | head -n1)

o segundo falhará e a segunda variável ficará vazia.

No entanto, se os revertermos, o varsnap1 falhará:

varsnap1=$(iscsiadm -m session | grep rbmsdata1 | head -n1)
varinit1=$(iscsiadm -m session | grep rbmsdata1 | head -n1)

É muito peculiar e não conseguimos descobrir o que está acontecendo. O comando iscsiadm está retornando a mesma coisa a cada execução quando o executamos na linha de comando e após o grep.

Há algo bagunçando a tubulação?

head versão 5.97 no RedHat Enterprise Linux

Responder1

Embora sua pergunta talvez contenha um erro (traço utf8 longo em vez do normal):

$ head –n1
head: cannot open ‘–n1’ for reading: No such file or directory
$ head -n1 # ctrl-d
$ 

Suponho que foi apenas uma coisa do navegador, já que apenas uma ocorrência foi assim. headespera pela entrada quando precisa dela de qualquer maneira. Tente substituir head -n1por um destes:

sed -n 1p
awk 'NR==1 {print}' # yay, no potential dash problems

Ok, existem muitas outras maneiras de fazer isso, mas você também pode pular esse elemento pipe e apenas dizer greppara retornar apenas a primeira correspondência adicionando o -m 1parâmetro. Ou eliminando dois elementos e dizendo perlpara operar apenas na primeira linha correspondente.

informação relacionada