スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

でぶぬる

昨日も書きましたが、振り返ってみると、このブログではいつも役に立たないことばかり書いているような気がするので、たまには役に立つ(?)ことを書いてみたいと思います。

ただし、お酒や断酒に関係した内容ではなくて、コンピュータに関する話です。このブログには、当初から、「その他」以外に3つのカテゴリを作っていて、「断酒」と「音楽」と「コンピュータ」の話を書こうと思ってブログを始めたんですが、「コンピュータ」の話題は書いたことがなかったので、一度、書いてみたかったんです。(というか、毎回、お酒や断酒のことばかりで、もうネタがないんです(泣)。)

なお、僕は、いわゆるパソコンや今流行りのスマートフォン等については、普通の人と比べても詳しくない方の部類に入るくらいなので、システムエンジニアの端くれとして、仕事をしていた時に使っていたコンピュータシステム寄りの話になります。

記事のタイトルの「でぶぬる」というのは、UNIXファイルシステムの「/dev/null」のことです。0バイトの空のスペシャルファイルで、一見、使い道がないようですが、標準出力や標準エラー出力に出力されたメッセージを抑制したい場合などによく使われます。

あとは、空のファイルを作成する場合などに使用されることもありますが、空のファイルを作成するだけだったら他にもいろいろな方法があって、人によって好みがあるみたいです。(こういう、UNIX的な思想や哲学が好きです。)

例1)空のファイルの作成方法いろいろ(太字はコマンド)

sh-3.2$ cat /dev/null > newfile1
sh-3.2$ touch newfile2
sh-3.2$ echo -n > newfile3

sh-3.2$ ls -s <- ファイル名とファイルサイズの表示
合計 0
0 newfile1 0 newfile2 0 newfile3


echoコマンドで空のファイルを作成する場合は、-nオプションをつけないと、改行コードが1バイト含まれてしまうので注意が必要です。また、touchコマンドは、本来はファイルのタイムスタンプを更新するためのコマンドなので、この用途では新規ファイルの作成の場面でしか利用できません。

それで、「/dev/null」の一般的な利用の仕方は、標準出力や標準エラー出力の出力が邪魔な場合に、以下のようにコマンドを実行して、「/dev/null」にリダイレクトします。その前に。。。

「いいか、絶対、rootで実行するなよ!君と僕との約束だからな!」(すいません、このネタを一度やってみたかったんです。)

例2)標準エラー出力のリダイレクト

sh-3.2$ cat /etc/shadow <- コマンドを実行
cat: /etc/shadow: 許可がありません <- 読み込み権限がないのでエラーが出力される
sh-3.2$ cat /etc/shadow 2> /dev/null <- 標準エラー出力を/dev/nullにリダイレクト
sh-3.2$ <- /dev/nullにリダイレクトしたので、エラーは出力されずにプロンプトが戻って終了

例2)を試してみて、最初のコマンド実行後、「許可がありません」というエラーメッセージが出力されなかったという方は、僕との約束を破った証拠です。さっさと、rootから抜けて、もう一度やり直してください。

で、ここまでは当然、少しでもUNIXをかじったことがある人にとっては何の役にも立たない話なんですが、シェルスクリプト中などで、例えば次のような処理を実現したい場合があったとします。

例3)シェルスクリプトで実現したい処理

sh-3.2$ cat /etc/shadow 2> /dev/null | wc -l
0
sh-3.2$ if [ $? -ne 0 ] ; then echo 'Error' ; fi
sh-3.2$
 <- 何も出力されずプロンプトが戻って終了(本当はここに'Error'を表示させたい)

えーと、何が言いたいかというと、1行目のパイプでつなげたコマンドの実行結果に何らかのエラーが生じた時に、3行目の戻り値の判定によって、画面上にechoコマンド等で'Error'と出力させたい場面があったとします。でも、通常、コマンドの戻り値を取得するのに使われる「$?」では、パイプの後のwcコマンドの実行結果によって判定されてしまうため、パイプの前のcatコマンドで発生したはずのエラーは、/dev/nullに標準エラー出力をリダイレクトしている状況では検知することができませんよね。

僕は、以前、会社を辞める前に最後に参加したプロジェクトで、この問題に直面して本当に悩みました。(もちろん、実際のスクリプトに実装しようとしていた処理はもっと複雑です。念のため)。「そんなのUNIX使いなら自分でコマンド作ればいいじゃん。」って言う人もいるかもしれませんが、そんな実力はなかったんです(きっぱり)。

それで、ネットで調べまくったところ、bashにはPIPESTATUSという変数が用意されていることを発見しました。

例4)PIPESTATUS変数の使用例

sh-3.2$ cat /etc/shadow 2> /dev/null | wc -l
0 
<- ここまでは例3)と同じ
sh-3.2$ if [ ${PIPESTATUS[0]} -ne 0 ] ; then echo 'Error' ; fi
Error <- PIPESTATUS変数の戻り値判定による出力

期待通りに「Error」と出力されました、感動モノです。ただし、このPIPESTATUS変数は、残念ながらbash限定の機能です。もし、bashが利用できない環境だったら、僕も参加していたプロジェクトを抜けられず、会社も辞めることができなかったかもしれません。(今となっては、そっちの方が良かったような気もしますが。)

今回は、このPIPESTATUS変数の紹介だけで、十分役に立つんじゃないかと思っていたんですが、記事を書くためにもう一度ネットで調べてみたところ、僕がこの変数の存在を知ってから4年近く経っているので、すでに知っている方も多いようです(もはや常識?)。その中で、この処理をbashを使わずに実現する方法を解説している方を発見したんです。(この人、すごい!ていうか、真のUNIX使いとしては当然?)

UNIXの部屋 コマンド検索: リダイレクト
http://x68000.q-e-d.net/~68user/unix/pickup?%A5%EA%A5%C0%A5%A4%A5%EC%A5%AF%A5%C8

リンク先のページの最後の宿題の部分が該当箇所ですが、今回使用したコマンドに置き換えて、実際に実行してみました。

例5)bash(PIPESTATUS変数)を使わない方法

sh-3.2$ exec 3>&1 ; status=$({ { cat /etc/shadow 2> /dev/null 4>&- ; echo $? 1>&4 3>&- 4>&-;} | wc -l 1>&3 3>&- 4>&- ;} 4>&1)
0
sh-3.2$ if [ $status -ne 0 ] ; then echo 'Error' ; fi

Error <- PIPESTATUS変数を使わずに$statusの戻り値判定で出力

素敵過ぎます。こんな方法、当時は思いつきもしませんでした。えっ、「2つ目のコマンドがエラーになった場合は?」って。そんなの「$?」で戻り値取れよ、うるせえな。「じゃあ、パイプでコマンドを3つ以上つなげた場合は?」って。そんな難しいことオレに聞くなよ、てかbash使っとけ。正直、どうしてこれが実現できるのかうまく説明できるほどには、よく分かってないんです。(しくしく。)

ところで、最近知ったんですが、UNIX系システムエンジニアの間では、「でぶぬる(/dev/null)」が大酒飲みという意味で使われることがあるんだそうです。ということは、キックオフの飲み会とかで、

「お前は本当にでぶぬるだな。」

なんて使うんですかね。いや、聞いたことがないんですけど。現場を離れてもう大分経つので、もしかしたら今は使うのかもしれません。うーん、このままじゃ社会復帰は遠いな。

また、くだらないことを書いてしまった。○| ̄|_

追伸:今回の記事で紹介したPIPESTATUS変数を使用しない方法は、他にも別のやり方が解説されているのは見つけたんですが、記述されている内容が正しいかどうか検証する余裕がなかったので紹介していません。別のやり方をご存じの方や記事に誤りを見つけた方はご教授下さい。<(_ _)>

ブログランキングに参加しています。よろしくおねがいします。
   ↓↓↓
にほんブログ村 酒ブログ 禁酒・断酒へ にほんブログ村 メンタルヘルスブログ アルコール依存症へ  

UNIXという考え方―その設計思想と哲学 Mike Gancarz (著), 芳尾 桂 (翻訳) 新品 ¥1,680

コメントの投稿

非公開コメント

もちろん全部読みましたよ

コメントバックありがとうございました。

>過去記事もかなりお読み頂いたようで有難うございました。

昨日、全部読みました。面白くて、涙が出ましたよ。同じこと2度言いましたが笑。
もう最高です。その証拠に、私のブログにリンクさせていただきましたよ。それも、「アメブロ以外」のリストの先頭に配置しました。
すみせん、事後承諾ですが、何卒、よろしくお願いいたします。 m(_ _ )m 

あと、これも、事後承諾で大変恐縮ですが、今日この後アップする記事に、ある記事を引用(リンク)させていただきました。これも、ご了解くださいませ。m(_ _ )m 

全部読んだ最後にコメつけます。唯一のコンピュータカテゴリの記事に背伸びして(見栄を張って)書いてみます。

私も、昔、UNIXマシンを一般ユーザとして使ったことがありました。CADを少し使わないといけなくて。そのCADがUNIXで動くやつだったので、仕方なくコマンドをいくつか覚えました。
でも、開発者じゃなかったので、スクリプトとかはあまり知らないのですが、パイプコマンドくらいはわかります。

私のレベルだと、例4まではなんとか理解できるけれど、例5は、よくわかりません。
せっかくなので、もし時間に余裕があったら、教えてください。

①4>&- の、&- とは何ですか? 出力を停止するということですか?

②私は、;というものを使ったことがないのですが、;は、何ですか?単に順番にコマンドを実行するということですか?後ろから順番にやるのかな?

③sh-3.2$ exec 3>&1 ;status=・・・(以下略)
このスクリプトは、ざっくり言えば、cat 以下のコマンドを実行して、その最終結果(この場合、"0"という出力)は、exec 3>&1によって標準出力に出力し、cat /etc/shadow の部分の標準エラー出力は、statusという変数に格納する、というスクリプトだ、という理解であってますか?

Re: もちろん全部読みましたよ

「優しくない名無し 」さん

> コメントバックありがとうございました。
>
> >過去記事もかなりお読み頂いたようで有難うございました。
>
> 昨日、全部読みました。面白くて、涙が出ましたよ。同じこと2度言いましたが笑。
> もう最高です。その証拠に、私のブログにリンクさせていただきましたよ。それも、「アメブロ以外」のリストの先頭に配置しました。
> すみせん、事後承諾ですが、何卒、よろしくお願いいたします。 m(_ _ )m 
>
> あと、これも、事後承諾で大変恐縮ですが、今日この後アップする記事に、ある記事を引用(リンク)させていただきました。これも、ご了解くださいませ。m(_ _ )m 
>

全部、お読み頂いたということで大変恐縮です。
(だいぶお時間がかかったと思いますので)

リンク、引用は大歓迎です、有難うございます。
ただ、少しは記事を更新しないと申し訳ないですね。

> 全部読んだ最後にコメつけます。唯一のコンピュータカテゴリの記事に背伸びして(見栄を張って)書いてみます。

すいません。この記事は内容は間違ってないと思うんですが、当時、あるひとりの読者に向けたジョークのつもりで書いたんです。今、読み返すと、恥ずかしいです。

> 私も、昔、UNIXマシンを一般ユーザとして使ったことがありました。CADを少し使わないといけなくて。そのCADがUNIXで動くやつだったので、仕方なくコマンドをいくつか覚えました。
> でも、開発者じゃなかったので、スクリプトとかはあまり知らないのですが、パイプコマンドくらいはわかります。

CADが使えるなんて、素晴らしいですね。

> 私のレベルだと、例4まではなんとか理解できるけれど、例5は、よくわかりません。
> せっかくなので、もし時間に余裕があったら、教えてください。

記事にもある通り、私もよく分かってないんです。(汗)
一応、分かる範囲でお答え致します。

> ①4>&- の、&- とは何ですか? 出力を停止するということですか?

「>&-」は出力を閉じるという意味です。

> ②私は、;というものを使ったことがないのですが、;は、何ですか?単に順番にコマンドを実行するということですか?後ろから順番にやるのかな?

「;」は前のコマンドが終わったら次のコマンドを実行します。
ちなみに「&&」は前のコマンドが正常終了(戻り値0)したら次のコマンドを実行します。
「||」は前のコマンドが正常終了しなかった場合(戻り値1以上)に次のコマンドを実行します。

> ③sh-3.2$ exec 3>&1 ;status=・・・(以下略)
> このスクリプトは、ざっくり言えば、cat 以下のコマンドを実行して、その最終結果(この場合、"0"という出力)は、exec 3>&1によって標準出力に出力し、cat /etc/shadow の部分の標準エラー出力は、statusという変数に格納する、というスクリプトだ、という理解であってますか?

statusに格納されるのは、標準エラー出力そのものではなくて、「cat /etc/shadow」コマンドの実行結果の戻り値です。この場合、statusには 1 が格納されます。

「優しくない名無し 」さんのブログも拝見させて頂きます。

有難うございました。それでは。

PR
つぶやき
買うもの
トブラデックス点眼液
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。