Linux
最近のLinuxでは、並列処理を行うことの難しいinitに代わってsystemdがよく使われている。
Linuxのコマンドラインインターフェースでは、シェルとしてbashを使い、grep, find, xargs, sed, awk, viのようなコマンドを用いてテキストストリームの編集や検索を行うことができる。
ほかのファイルシステム操作関係のコマンドとしてはmount, fdisk, parted, mkfs, mkswap, du, df, dd, rsync, tar, chrootなどがある。
また、ネットワーク関係のコマンドとしてはifconfig, iproute2, netstat, route, traceroute, nslookup, ping, sshなどがあり、モニタリング系のコマンドとしてはtop, iostat, vmstat、プロセス表示・強制終了コマンドとしてはpsやkillなどがある。
また、ネットワークファイルシステムとしてNFS、SambaやFTPサーバ・クライアントソフトウェアが利用できる。WebサーバソフトウェアにはApacheとNginxがある。定期的にコマンドを実行するソフトウェアとしてはcronが知られる。
GNOME 2については、GNOME 3の大幅なユーザーインターフェースの変更に否定的かつ旧来のインターフェースを支持するユーザによってMATEが派生している。同様のKDE 3から派生したTrinityがある。
LinuxはWindowsとは違ってコマンド主体のOSであり、操作もGUIだけではなくコマンドラインやプレーンテキストの設定ファイルなどを駆使して行うが、こうした「Windowsとの違い」はWindowsしか知らない現代のパソコンユーザーには興味深い。そのため、「純粋に楽しみのためにLinuxを使う」という層はいくらか居る。特にLinuxはオープンソースのOSであり、コストをかけることなく導入することができる。そのため、「試しに使ってみたらけっこう面白かった」「コマンドで操作するのはGUIとは違った面白さがある」といったホビイストのLinux愛好家は多い。特にリーナス・トーバルズなどを中心にインターネット上で開発されているOSであるため、「ネットのLinux関連の情報やニュースに詳しくなる」という楽しみ方が存在し、オープンソースであることなどからOS内部の仕組みを知ることが容易で、「どんどん詳しくなってどんどん深みにはまる」という面白さがLinuxにはある。
Linuxとオープンソース
GPLでライセンスされていることにより、GPLを守る限りにおいて、Linuxのソースコード(プログラムとして記述されたソフトウェアの設計図)の改変・コピー・再配布が許される。ソースコードが公開されていることにより、誰もがLinuxのプログラム内容を閲覧することができ、編集して自分なりに書き換えた後に実行することも、編集後の結果をインターネット上で発表し、パッチを公開することもできる。しかしながら、GPLにおいては、配布する際にソースコードを必ずユーザーに公開する必要がある。また、少しでもGPLソフトウェアのソースコードを用いて開発したソフトウェアは、GPLでライセンスしなければならない。これを「継承条項」あるいは「コピーレフト」などと呼ぶ。こうしたGPLの特性のため、Linuxカーネルのソースコードを第三者が「自分のものにする」ことはできず、同様のGPLライセンスが半永久的に保たれ続ける。つまり、永久にLinuxカーネルは自由にコピー・改変・再配布が可能なままとなる。こうしたGPLの特性は、「ウイルスのようだ」といって批判されることも少なくないが、GPLを裁定しているFSFやGNUプロジェクトは、X Window SystemのMIT/Xライセンスのような緩いライセンスでは、永続的に自由を保つことができず、そのためもともとのXがフリーであったにも関わらず、多くのUNIXではXはフリーではなかったなどと説明している。
また、オープンソースには「無保証の原則」がある。これは、「無償でどんなに自由に使っても構わないが、きちんと動くかどうか保証はしない」というものである。よって、作る側ではなく使う側に責任があり、どんなに劣ったソフトウェアであっても開発側に責任を求めることはできない。しかしながら、Linuxディストリビューションには、商用で高額なライセンス料金を取る代わり、動くことを保証(サポート)するものもある。Red Hat社のRHELなどがこれに当たる。RHELは、もっとも安いエディションで10~17万円ぐらいの価格となっている。エンタープライズシステムなどで、保証と長期サポートが必要であれば、こうした商用のLinuxディストリビューションを購入することも選択肢になる。
また、Linuxは「バザール開発」と呼ばれるオープンソースの開発モデルを採用している。「オープンソース」はエリック・レイモンドによる用語で、「乱交まがいにオープンにし、パッチをとりこみまくる」という、一見成功するように見えない開発モデルだが、リーナス・トーバルズの高い技量と、インターネット上の善意の開発者の「たくさんの目玉があること」により、Linuxカーネルは急速に、現代的機能の豊富な安定し信頼できるカーネルへと成長した。しかしながら、Mozilla.orgの失敗例(いつまでも安定したバージョンをリリースできなかった)のように、「オープンソースは必ずしも魔法のお鍋ではない」とも言われている。
Linuxにおいてユーザーランドの多くを構築するGNUプロジェクトやFSFは、GPLを積極的に押し進めることで、「全てのコンピュータユーザーにフリーソフトウェアを提供し、コピーなどの自由な権利を守ること」のために活動している。
Linuxとオープンソースについては、このような批判的意見があるにも関わらず、Linuxに多くの場合付属するパッケージソフトウェアとして、カーネルだけではなく開発ツール(コンパイラ、インタープリタからX Window SystemやGUIツールキットまで)、サーバーソフトウェア、データベース管理システムなどがほぼ全てオープンソースのライセンスで提供されることから、「無償で開発環境を得たい」とするシステム・エンジニアや学生・入門者の間で、実用あるいは教育・研究用としてLinuxシステムは広く使われている。また、UNIX系のOSであることから、FreeBSDなどと同じように「高負荷になっても耐えられる」という特徴があり、このことからWebなどのサーバーシステムにおいてもLinuxは広く使われている。デスクトップOSとしては、多くの場合標準として採用されているGNOMEなどを別のデスクトップ環境やウィンドウマネージャにカスタマイズして取り換えたり、多くのオープンソースパッケージ(MS-Office代替のOfficeソフトウェアなどを含む)を簡単に導入したりすることができるため、「Geek」(オタクの意味)の間で愛好家が多い。エンタープライズシステムとしては、UNIXと同様IBMのメインフレームよりも安価な「オープン系」のシステムとして、性能や可用性を重視するクラスタや、GoogleのようなIT企業の用いる巨大データベースなどにOSとしてLinuxが使われることも一般的になってきている。
パッケージ
LinuxがFreeBSDのような他のUNIX系OSと異なる点は、さまざまなパッケージの寄せ集めであること。Linuxという言葉が意味するのはカーネルだけであり、多くの場合ディストリビューションとして配布されているパッケージの集合をインストールする。これはFreeBSDなどのOS一式を開発するモデルとは対照的だが、あるひとつのプロジェクトが全てを支配するのではなく、さまざまなシステムが有志によって開発されるという「多様性」のメリットがある。また、さまざまなパッケージがGPLやパーミッシブ・ライセンスでそれぞれ配布されていることが、全体の大きな共栄圏である「コミュニティ」を形成する。これは企業においても例外ではなく、現にChromiumやMozcのようなオープンソースパッケージはGoogleのような商用企業によって開発されたものが、ディストリビューションによって配布されている。オープンソースは再配布やコピーが許されるため、こうしたコミュニティの作ったオープンソースパッケージをディストリビューションのリポジトリで再配布できる。また、最近ではFlatpakのような仕組みもあり、ディストリビューションのパッケージとサードパーティのパッケージを(主にデスクトップ向けに)分離し、ユーザがパッケージを導入しやすくする試みも行われている。
このようなディストリビューションによるパッケージ版のバイナリは、多くの人が「寄せ集め」と言って想定するのには反して、パッケージのメンテナがきちんとシステムとの整合性を考慮してパッケージ化しているため、多くの場合、特にDebianやRed Hatのような大手ディストリビュータの場合、自分でtarballをmakeしてビルドするよりも、期待される通り動くことが多い。セキュリティパッチやバグ修正などの更新サポートも受けられるため、信頼性が必要なサーバーなどのシステムにおいては、ディストリビューションのパッケージを導入することが推奨される。特にRHELのような商用ディストリビューションはサポート期間が長く、サブスクリプション契約によって最新のシステムにアップグレードすることも、変更することなく既存システムを保守することもできる。
また、最近ではコンテナ仮想化技術であるDockerを仮想サーバのために利用することができ、Docker Hubを利用すれば、パッケージをインストールする必要すらなく、dockerコマンドだけで必要なサーバのコンテナイメージを導入することができる。Kubernetesを使えば、Docker環境における複数ホストの連携を簡単に行うことができ、面倒な作業なしに巨大クラスタを構築できる。こうした技術により、Linuxは急速に仮想サーバ・コンテナクラウド市場で有力なOSとなりつつある。また、DockerはLinux上で動くコンテナ型仮想化システムだが、Linux自体をWindowsやmacOSで動かすためにVirtualBoxやVagrantを使うことがある。
また、以前のLinuxやオープンソースでは、開発に参入する障壁がとても高かったが、最近はGitなどの高度なツールやホスティングサイトが増え、オープンソースの開発に参入する障壁がとても低くなった。gitのコマンドを使い、GitHubやGitLabなどのホスティングサイトにアカウントを登録すれば、誰でも簡単にリポジトリをクローンして変更をコミットし、リポジトリにプッシュしてプルリクエストをすることで、自分の変更をすぐさま登録できるようになっている。GitはLinuxカーネルの開発のために作られたバージョン管理システムで、前世代のCVSやSubversionに比べて高パフォーマンスであることで知られている。
カーネル
カーネルはオペレーティングシステムの中核となるソフトウェアであり、以下のような機能を実現する。
マルチタスク
コンテキスト切り替えと仮想アドレス空間により、複数のプログラムを同時に実行することができる。
コンテキスト切り替えは、とても小さな時間でプロセスを次々に切り替えて実行し、その際CPUのレジスタの内容を(Linuxにおいては)task_structと呼ばれる構造体に退避してプロセスを安全に停止・再実行する。
仮想アドレス空間は、プログラムがメモリ上のアドレスにアクセスした時点で、カーネルが論理アドレスを物理アドレスに翻訳する。
このようにすることで、CPUとメモリがたとえ1つしかなかったとしても、それぞれのプログラムの数だけあるかのように仮想化することができる。
デバイスドライバ
カーネルはデバイスを操作するために、デバイスドライバという仕組みを使う。
それぞれのデバイスドライバがデバイスコントローラの詳細を知っており、カーネルはデバイスドライバを介してハードウェアデバイスにアクセスする。
デバイスにはキャラクタ型デバイスとブロック型デバイスがある。
プロセス・スレッドとプロセス間通信
プロセスはそれぞれの独立したメモリ空間を得るが、スレッドはひとつのプロセスの中で複数のスレッドを並列実行し、同じメモリ空間を共有する。
しかしながら、プロセスにおいても、プロセス間通信を利用することで、メモリやデータを共有することが可能となる。
シグナル
カーネルは、プロセスを強制終了するためにシグナルを利用する。
何の指定もされていない時、カーネルはシグナルの扱いについてデフォルトの動作を行うが、シグナルはユーザープロセスの側で「トラップ」することができる。
この時、シグナルを受信したプロセスがどのように対応するか、プロセスの側で書き換えることができる。
ファイルシステム
カーネルはファイルシステムとして、ストレージにおけるデータを格納することができる。
代表的なファイルシステムに、Linuxのブロック型ファイルシステムであるext2やext4、LinuxにおいてB-Tree方式を採用したReiserFS, XFS, Btrfsなどがある。
ネットワーク
カーネルは、ネットワーク通信におけるソケットインターフェースをサポートしていることがある。
ソケットはUNIXにおけるファイルシステムと同様のネットワーク通信インターフェースであり、BSDにおいて実装された。
ソケットは互いに接続したときに有効となり、片方に書き込むと片方から読み込むことができる。
ソケットを介してカーネルはネットワークインターフェースにおけるTCPやUDPのプロトコル通信を行う。
TCPは多くの機能があり、誤りを検出した際に再送制御を行ったりすることができる。
UDPはそうした機能がない代わり、ビデオや音声などを送る際に多少の誤りがあっても無視してデータの送受信を高速にやりとりすることができる。
入出力とシステムコール
カーネルは、プロセスが要求するシステムコール呼び出しに対してサービスを提供する。
典型的なのは入出力やファイルシステム操作であり、たとえばopen(), close(), read(), write()といったシステムコールに対してファイルの読み書きや入出力(IO)処理を請け負う。
また、システムコールに加えて、C言語のライブラリがstdioとして用意する標準入出力のAPIがあり、これはたとえばprintf()やfgets()などが挙げられる。
stdioはバッファ処理を行うためシステムコール呼び出しよりも高速にリソースにアクセスでき、また固定長の入出力だけではなくバイト単位(1文字ごと)や行単位の入出力APIをサポートしている。