パイプ grep/head の奇妙な動作

パイプ grep/head の奇妙な動作

私はここで、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/')

スナップショットのシグネチャには 2 つの部分があり、一方が他方にネストされており、キャプチャ グループを使用して、実行する必要のあるさまざまな後続のコマンドの名前と名前の一部をキャプチャしています。同じコマンドが何度も実行されており、正規表現は後でクリーンアップできることはわかっていますが、基本的には、1 つの括弧ともう 1 つの括弧を出力するために 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 へのパイピングが、次のように失敗することがあることです。

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)

2 番目は失敗し、2 番目の変数は空になります。

しかし、これを逆にすると、varsnap1 は失敗します。

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

これは非常に奇妙で、何が起こっているのかわかりません。iscsiadm コマンドは、コマンドラインから実行した場合と grep した後で、実行するたびに同じ結果を返します。

配管に何か不具合がありますか?

RedHat Enterprise Linux 上の head バージョン 5.97

答え1

質問にはエラーが含まれている可能性があります (通常のダッシュではなく長い utf8 ダッシュ)。

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

そのようなケースは 1 回だけだったので、これはブラウザの問題だと思われます。headいずれにせよ、必要なときに入力を待機します。head -n1次のいずれかに置き換えてみてください。

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

他にもたくさんの方法がありますが、パイプ要素をスキップして、パラメータgrepを追加して最初の一致のみを返すように指示することもできます-m 1。または、2 つの要素を削除して、perl最初に一致した行のみを操作するように指示することもできます。

関連情報