brand new note

ジャズ屋が技術の話をするところ

manページの番号が持つ意味

ずーっと疑問だったのがちょっと解決したのでメモ。まずmanページに番号がなぜ必要なのか、加えて番号を使うことでどのようにコマンドを扱うことができるのかについて書いていきます。

manページに番号がある意味

コマンドのマニュアルであるmanページですが、たまに番号つきで説明が出てくるコマンドに遭遇します。これが何なのかまず簡単に言うと、こういった場合「同じコマンドなんだけど複数の意味、使用用途がある」ということを表しています。同音異義語と似ていますね。例としてtimeコマンドを見てみます。

# man 1 time

f:id:frazz:20180408025752p:plain

# man 2 time

f:id:frazz:20180408025917p:plain

timeの一つ目の意味としては「コマンドの時間計測やリソース使用量を表示する」、二つ目の意味としては「秒単位の時間を得る」とあります。このように複数の意味が存在するコマンドは、”man 数字 コマンド” でそれぞれの意味を確認することができます。これだけ知っていればしばらく困らないとは思いますが、ここで注意してほしいのは「コマンドの使い方が複数ある」ではないということです!追って説明します。

manページの番号が持つ意味

えっでもどっちも時間見てるだけじゃんと思った方、ここで上図の「書式」を見比べてみてください。1ではコマンドの文法が書かれているのに対し、2ではC言語らしきものが書かれていることがわかります。

システムコール

そもそもUNIXのコマンドはC言語を基にして作られています。またOSの様々な制御は「ユーザモード」と「カーネルモード」の2つを用いて行われており、ここを命令が行き来することによってプログラムは動作しています。

普段プログラムはユーザモードで動作しているのですが、ハードウェア(CPU)に直接命令を下したい場合はその都度「システムコール」を使ってカーネルモードにアクセスします。

ちょっと説明のために脱線しますが、ここでlsコマンドの内部でどのようなシステムコールが行われているか確認してみます。

f:id:frazz:20180408032307p:plain

なんかexecveとかopenとかmmapとか書いてありますね。これが全部システムコールです。要するにlsコマンドを打つだけで、内部ではこれだけの回数カーネルモードに遷移しているのです。これらが何なのかは細かい説明になるので書きませんが、ここで下のコマンドをちょっと試してみてください。

man 2 execve
man 2 open
man 2 mmap
man 2 mprotect

書式の所がC言語になってmanページが表示されたでしょうか?

つまり、manページの2番はシステムコールの説明をしているのです。通常のコマンドとしてのtimeはその場で時間を測定する効果をもたらしますが、システムコールとしてのtimeは、何かのコマンドを実行した時に「そのコマンドが内部的に何かの時間を計測した上で結果を返す」というような挙動をする時、使われているという事なのです。

manページの書式内のC言語システムコールの実装そのものであり、コマンドはC言語で作られたシステムコールの集合であるということがお分かりになると思います。

番号と意味の対応

マニュアルの番号はセクションと呼ばれます。1、2以外にもありますので記載しておきます。また、OSによってこれらの番号の振り分け方は異なる場合があります。

  • 1:ユーザコマンド

  • 2:システムコール

  • 3:システムコールを除くCライブラリ関数

  • 4:デバイスファイル

  • 5:設定ファイルなどのフォーマットについて

  • 6:ゲームプログラム

  • 7:その他の概要などの説明

  • 8:システム管理コマンド

例えば1のユーザコマンドだったらlsとかcpとかが含まれますし、4のデバイスファイルだったらnullとかzeroとかttyとかが該当します。*1 一つしかコマンドの意味が存在しない場合はそんなに気にしなくても参照できますが、こういうのがあるとだけ分かっておくといくらか読みやすくなると思います。

おわりに

コマンドを覚えて操作できることを目標とする段階ではなかなか理解しにくい面があるかもしれません。linuxの内部的な話をいろんなところで少しずつ読んで理解すると、このあたりの話も納得できるのではないかと思います。

あ、偉そうに書きましたが間違っていましたら御指摘お願いします。僕も勉強中の身ですので。。。

Windows Subsystem for Linuxを使ってみる

かつてbash on ubuntu on windowsと呼ばれたWindows Subsystem for Linuxをインストールしてみました。

WindowsLinuxが使える??

Windowsの中でLinuxを使えたらもっと手軽にいろいろ試せるのに、、と思った途端、そういえばなんかあったなあと思い出したのでインストール。まあ特にこれといってやりたいことはないんですが。動作したはいいものの、どういう仕組みで動いているのか気になったので調べました。

仮想化とは違うのか

f:id:frazz:20180407230506p:plain

/mntディレクトリを見てみると、CドライブやDドライブがあるのを確認できます。仮想化とは違って本当にWindowsとシステムが共存しているようです。IPアドレスも確認しましたが、Windowsで使っているいつものアドレスと同じ値が使われていました。VMWare Network Adapter VMnetのアドレスもそのまま使われていました。

調べたところ、現在のwindowsマイクロカーネル(UNIXのようなモノリシックカーネルと違い、カーネル部を最小にしてその他多くの機能をモジュールとして読み込む考え方)で動作しており、その上に複数のサブシステムを共存させることができるようです。いつものGUIwindowsサブシステムと呼ばれるもので、これに沿ってLinuxもサブシステム化して動作させることは可能というわけです。

Windows Subsystem for Linux(WSL)はPicoプロバイダードライバという2つのカーネルドライバで実装されており、Windows側でlinuxセッションマネージャサービスがWSLのセッションを呼び出し、その先でbashをforkするという流れになっているようです。下図はmicrosoftのブログから引用しています。

f:id:frazz:20180407232252p:plain

何が便利なのか

まず仮想化に比べると、ファイルの転送がとても楽です。一応Cドライブの中身は/mntに入っていますがそれ以外はまっさらなので、/homeなんかには何も入ってません。なのでその中でlinuxでやりやすい作業をして、その後作ったファイルを/mnt配下に持っていくことで簡単にデータの共存ができます。

加えてネットワーク構成がwindowsとほぼ同じなので、デスクトップ環境でターミナルソフトを立ち上げるところを、sshコマンド一発で入りたいサーバに入れます。それらのサーバとファイル転送をしたいときもwinscpとかいちいち立ち上げなくて済みます。これほどちょうどよくwindowslinuxの使いやすいところのいいとこ取りができる技術があったなんて。。。

今のところ自分が見つけたのはそのくらいですが、特にプログラムを書く人にとってはこの恩恵を大きく受けることができるのではないかと思います。officeで資料作りながらコマンドラインで開発できるわけなので。

はじめの一歩に使えるリンク

インストールのしかたと概念はこのへん読めばいけます。

root取れない問題

一瞬詰まる方も多いので参考までに。WSLでルートが取れない問題に関しては、こちらの情報が有効です。

bash on Windows の root のパスワードは | Windows 10

初期パスワードは不明とのことですがsudo は効くので、次のコマンドによってrootパスワードは自分で変更できます。

sudo passwd root


OpenstackとAnsibleの関係性がわからないので調べた

タイトルの通りです。最近よく聞くAnsibleっていうのが何なのかさっぱり分からず、自動化とか構成管理とかいう言葉と一緒にに流れてくるのを見てOpenstackっぽいサムシングを連想したんですがどうなのか。技術的なことは書いてませんが、調べているうちに背景や今の流行がなんとなくつかめたのでその辺を網羅的にメモします。

とりあえず読むじゃん

qiita.com

www.ntt-tx.co.jp

www.slideshare.net


Infrastructure as a Code

Infrastructure as Code(IaC) というのは、物理的なハードウェア構成やインタラクティブな設定ツールの使用ではない。コンピューティング・インフラ(プロセス、ベアメタルサーバー、仮想サーバー、など)の構成を管理したり、機械処理可能な定義ファイルを設定したり、プロビジョニングを自動化するプロセスである。

Wikipediaより。DevOpsとの関係性の部分ではこのように記されています。

IaCはDevOpsのベスト・プラクティスを実現する重要な要素だろう。開発者はもっと構成の定義に参加するようになり、運用チームは、開発プロセスの初期段階で入ってくるようになる。IaCを活用するツールはサーバーの状態・構成を視覚化し、企業内のユーザーに視覚性を提供し、最終的に努力を最大限にするために、チームを結集することを目指している。 一般的に、自動化は、手作業のプロセスの混乱とエラーの起こりやすい部分を取り除き、より効率的かつ生産的にすることを目指している。手動構成の効率を低下させる複雑さを軽減することも目的としている。柔軟性が高く、ダウンタイムが少なく、全体的に費用効果が高いソフトウェアとアプリケーションを作成できる。 自動化と共同作業は、DevOpsの中心的なポイントであるため、多くの場合、インフラストラクチャ自動化ツールはDevOpsツールチェーンのコンポーネントとして含まれている。


要するにクラウドサービスが盛んになった現在では、開発から運用までをチーム一体となってカバーすることが容易になった。それに伴ってサービス設計の初期段階である「インフラ構築のフェーズ」を様々な技術者に理解してもらいやすくすることが必要となってきた。その為にあれこれを自動化、可視化してより簡単に扱えるようにしよう、という思想が広がり、これがInfrastructure as a Codeと呼ばれるようになった。

で合ってますかね!?

いっぱいサーバが並んでるところで一台一台手作業でソフトを入れたりするのはありえんしんどいので、すべてのサーバが同じ挙動をする仕組みができれば一発で大規模システムも管理できて幸せだよね、という話なんでしょうか。そういえば米microsoftは一人当たり数千台のサーバを管理しているとかいう噂を本で見たのですが、確かにこういうところでならかなりの効率化が期待できますよね。その構成管理のツールのひとつがAnsibleなんですね。

インフラ屋もコードを書くのか

他の構成管理ツールであるChefの場合はRubyベースの定義ファイルに基づく設定が必要です。しかしAnsibleの場合、yamlというマークアップではないけどプログラミング言語でもない記述方法によって簡潔に設定ができるようです。Ansibleの実装はPythonなので詰まったら実際のソースを読んでデバッグすることはあるんでしょうけど、特にPython書けなくても動かすことはできます。これなら俺にもできるだろうか。。。

ぼんやり「インフラエンジニアもこれからはコード書けないといけないということ…?」と思っていましたが、そうともいえるしまだそうでない仕事もある、でもできないと時代に取り残されるかもしれない、という認識です。学ばねばならぬ。

OpenstackとAnsibleの関係

OpenstackのモットーはVMそのものを構成する部品を作る(ブロックデバイスやネットワークIO、認証系など、コンピュータとして必要な機能をまず提供する)とでもいうべきでしょうか。そして、その中で提供する部品の一つに「自動化を助ける機能」があり、ここでChefやAnsibleといったツールが連携します。ソフトウェアの導入、サービスに応じたネットワーク設定等をするための機能です。Openstackの上にAnsibleがのっかっていて、その上に開発するサービスが動くということでしょうか。

またAnsibleはその特性から、短いスパンで改良を遂げているOpenStackとは思想が近く、相性がいいようです。Ansibleは構築したサーバにエージェントを置く必要がなく、端末からsshで設定を流し込むだけで柔軟かつ容易に構成の自動化を行えるからです。逆にあまりにも大規模なサービスの場合はエージェントを置いたChefのほうが良いみたいですね。

/dev/zeroってなんだ

/devはデバイスのdev。データの入出力装置に関する情報を管理しているディレクトリです。/dev/xxxという形でハードディスクやUSBメモリ等、様々なデバイスの情報を格納しています。

/dev/zeroとは

0x00を常に出力し続ける特殊なデバイスのことをさします。とりあえずダミーファイルを作りたい時や、ディスクを0x00で埋め尽くしてデータを消去したい時に用いることができます。一歩間違えると危険そうですね。。。なんか右下にありますね。

f:id:frazz:20180402145316p:plain

/dev/nullとの違い

0x00でデータを埋め尽くしてファイルを作るとファイルサイズがちゃんと0の分だけ存在してくれます。対して、null文字で埋め尽してファイルを作るとファイルサイズは0バイトになります。といってもよく分かんないのでやってみましょう。

f:id:frazz:20180402150555p:plain

検証にddコマンドを使います。bsはブロックサイズ、ifはinput file, ofはoutput fileの略だと思います(たぶん)。/dev/zeroを入力元としてtestファイルを錬成すると、ちゃんとファイルサイズが1000バイトになっていますね。moreで見てみると1000バイト分の空白があるのも確認できます。

次に/dev/nullから同じようにファイルを練成します。

f:id:frazz:20180402151210p:plain

1000バイトと指定してもファイルサイズは0バイトのtestファイルができてしまいました。これが「何もない」と「0がある」の違いです。データっておもしろい。今後何かに使えればいいのですが。。。

参考

qiita.com

ここの方が詳しく載ってますので興味があれば。

個人slackをはじめたらだいぶ良い感じって話

slack.com

slackというツールをご存知でしょうか?コミュニケーションツールの一つなのですがLINEとは雰囲気が全然違っていて、トークルーム(チャンネル)の管理やチャットがスマホだけでなくPCでも柔軟に出来るのが特徴です。自分も研究室に入ってからはLINEと同じくらい利用していて、社会人の方も使っている方は多いのではないかと思います。

メインはコミュニケーションツールとして使うslackですが、ちょっと教わって「個人でやるslack」がとても便利だということを知りました。メモ。

普通に高性能なメモ帳として使える

qiita.com

大体この記事を読む場合が多いと思うので挙げておきます。まずコミュニケーションの場の単位としてもっとも大きいのがワークスペースです。ワークスペースを作ることは誰でもできるので、まず自分用のワークスペースを作成します。

で、誰も招待せずにチャンネルには「ここはこのメモ!」と分かるように名前を付け、それらを一人で全部使うのです。

こうすることにより日々のタスクやらメモやら独り言を掲示板形式で書きためておく事が出来ます。

アプリ連携が非常に強い

で、アプリケーションの連携が非常に高機能なところもslackの強みです。twitterの情報を垂れ流すこともgoogleカレンダーやtrelloのタスク管理と連携*1することもできますし、githubともインスタともOneDriveとも連携できます。なんでもできます。

スマホにアプリが沢山入っている方も連携機能を使いこなせばslack一つ見るだけで様々な用事を済ませることができるかもしれません。

f:id:frazz:20180328231326p:plain

ちなみに自分は連携機能についてはまだまだ使いこなせてないので、シェル芸botを垂れ流すくらいしか使用用途を思いつくことができません*2。既にだいぶ楽しいですけど。こんな感じで、チャンネル毎に色々メモを残しておくことができますので、最近はノート取るのはネットが使えない外出先だけになってきました。PCが使えて家で一人で作業ができる時のメモはほとんどこっちにシフトしましたね。

おわりに

slackを知ってる方は結構この使い方をしている方が多いので今更感があるかもしれません。しかし知らない方や使って日が浅い方には全く馴染みがないと思います。コミュニケーションツールとしても、予定管理やメモのツールとしても非常に有用なのでおすすめです。

tmuxのはじめの一歩

tmux歴1年くらいになったのでちょっとまとめ。ずいぶん前から書こうとしていたのですが放置していました。

tmuxとは

1つのターミナルで複数のサーバにログインし、同時にセッションを保ちながら作業ができます。これがないと複数のサーバに一度にアクセスして作業したいときに1つずつターミナルを立ち上げなきゃいけないので、あるととても便利。一度このサーバとこのサーバに入って作業がしたい!ってなったら、未使用中でもその作業環境を保存できます。

参考サイト

自分の記事より100万倍参考になるサイトを先に紹介しておきます。

概念はここ読めばいいと思います。

基本的にはこのへん読めば使えます。

強い人はこういうことしてるらしいです。

とりあえず、基本的な説明も以下に示します。


セッション、ウィンドウ、ペイン

まずtmuxには3つのキーワードがありますので頭にいれましょう。

  • セッション:tmux全体で管理しているサーバへのセッション情報(接続情報)

  • ウィンドウ:接続した先のウィンドウ。

  • ペイン:ウィンドウは分割することができる。分割したものの一部をペインという。

次に実際にtmux実行時の画面を使って説明します。みんなもやってみよう!!

ペインを割る

# tmux

f:id:frazz:20180328170349p:plain

起動しました、下が緑色になってウィンドウの名前を表示しています。このようにただコマンドを打つだけでも起動しますがこれでは使う意味がありませんので、ペインを分割してみます。Ctrl+b→%と入力してみます。

f:id:frazz:20180328171149p:plain

ウィンドウが横に割れました。次にCtrl+b→” と入力してみます。

f:id:frazz:20180328172401p:plain

そこからウィンドウが縦に割れました。このように一つの画面で複数のターミナルを開くことができます。あと、隣のペインに移動する時はCtrl+b→矢印キーです。ペインを消すときはCtrl+b→xです。まずはこれだけ覚えると作業してる感に満ち溢れてテンションが上がると思います(?)。

ウィンドウを増やす

しかしペインを割るだけではどんどんひとつの作業スペースが狭まります。新しいウィンドウを作るにはCtrl+b→cです。

f:id:frazz:20180328173205p:plain

新しいウィンドウが作られ、下にウィンドウ0とウィンドウ1が見えますね。このように作業スペースが確保できない場合はウィンドウを増やします。ウィンドウ間を移動する時はCtrl+b→n もしくは Ctrl+b→p です。(nextとprevだと思います)

Ctrl+b ってなに

散々出てきているCtrl+bはプレフィクスキーと呼ばれます。要するにtmuxの処理を行うために必要な最初のコールのようなものです。使いこなせるようになったら独自のキーバインドを作ることも可能ですので、段々自分の作業がしやすいようにカスタマイズできると楽しいと思います。

セッション管理

ここまでできたら普通にターミナルを開くよりも、確実に一度に様々なアクセスができるようになっていると思いますが、こことここにアクセスした記録をそのまま残して次回以降は一瞬で立ち上げたいという欲が湧いてきます。

ここで使えるのがセッション管理の概念です。

本記事を見ながら手を動かしている方はCtrl+b→dしてみてください。

f:id:frazz:20180328174949p:plain

tmuxが消えて元の画面に戻りました。これをセッションを抜ける、デタッチするといいます。今作業していた直前のセッションにもう一度入る、アタッチするには以下です。

# tmux attach

過去に名前を付けて保存したセッションに再度入るには以下です。

# tmux attach -t [session name]

はい、セッション名の話もしないといけませんね。直前の環境だけでなく、この作業環境とこの作業環境を分かりやすく残しておきたい。。。という場合は起動時に予めセッション名をつけます。

f:id:frazz:20180328180257p:plain

ここからは上図の説明になりますが、tmux new -s hogehogeというセッション(作業環境)を作成しています。tmux ls することで現在作られているセッションを見ることができます。いらないセッションはtmux kill-session -t [セッション名]で消すことができます。

注意事項

ここまで覚えたらあとはもっと便利に使えるように調べていくのがいいと思います。ただ、セッションの概念を理解せず普通にexitとかしてtmuxを閉じてしまうと、一度作った作業環境が保存されず作り直しになったりすることになります。

また、exitもせずCtrl+b→xでペインだけ消してそのまま全部作業環境を消してしまうと、サーバに接続している情報が残ったまま作業環境が消えてしまうことになります。こうなるとログアウト作業が別に発生してしまいます。(自分はこれで2週間サーバに知らずにログインしっぱなしになって注意されたことがあります、勉強にはなりましたが。。。)

というわけで、tmux初めての皆さんもこちらに気を付けて作業していただければと思います。では。

C言語のめも:03/26

パケットを投げるプログラムを拾ってきたので読んでいます。。。

ソケットプログラミングのヘッダファイル

  • sys/socket.h
  • netinet/in.h
  • arpa/inet.h

L3L4ヘッダ定義用のヘッダファイル


hexdump([バッファ用メモリアドレス][index])

main関数の中で呼び出されたらindexのぶんだけバッファのアドレスを出力? デバッグ用?

  • uint8_t

  • uint16_t

  • uint32_t

型。ヘッダ情報を構造体で作る、IPとプロトコルとレングス?


main関数

argvはプログラムに渡す引数の配列?

IPはポインタで??

char *data:IPヘッダの最終番地を入れる、ペイロードの開始番地に等しい? 細かいヘッダの中身はmain内で定義されている、代わりに大まかな作りは関数にまとめている

TCPヘッダ、synフラグだけ1になってる

ウィンドウサイズ:htons(155)とは。。

送るbyte数はsendto()の中で定義されたものが代入される

送れない場合はbyte数が負の数だったときと仮定してperrorを返す