一口に「nlコマンド」と言っても様々な実装があります。機能に大きな差はありませんが、この記事ではnl
の種類とその調べ方について説明していきます。
nlコマンドの種類
最初のnlコマンド
最初にnl
が実装されたシステムは、1984年に発売されたAT&Tの「System V Release 2(SVR2)」のようです。FreeBSDのドキュメントにはこのような記載がありました。
HISTORY
The nl utility first appeared in AT&T System V Release 2 UNIX.
出典:https://www.freebsd.org/cgi/man.cgi?query=nl
さらには1987年、X/Open Portability Guide(issue 2)で標準化され、POSIXやSingle Unix Specificationといった後の主要な標準ドキュメントにも記載されていきます。30年以上の歴史あるコマンドですから、今回紹介する実装以外にも様々なnl
が存在することでしょう。
GNU coreutils
GNU coreutilsは多くのLinuxディストリビューションで採用されているnl
を含む主要なコマンドユーティリティです。他の実装に比べて、GNUによる独自の機能拡張や性能改善がされています。この拡張が互換性や移植性の問題を引き起こすこともありますが、個人的な利用において過度に気にする必要は無いでしょう。
執筆時点の最新版はv8.32で2020年3月にリリースされたものです。最近のLinuxディストリビューションでは、RHEL8やCentOS8、Ubuntu 20.04LTSではv8.30が、Ubuntu 20.10ではv8.32が採用されているようです。
BSD系(macOS、FreeBSD等)
BSD系のnl
は単一の提供元が存在するわけではなく、*BSDの実装を元にAppleなどの各OSベンダーが必要に応じた改変を加え提供しているnl
の総称的なものになります。もちろん細かな挙動は各々の実装で異なる可能性がありますし、プロプライエタリな実装もあります。
ちなみにAppleのSource Browserによると、macOSではNetBSDの実装が使われているようです。
busybox
ルーターなどのLinux組み込み機器では、コマンドユーティリティにbusyboxが採用されていることがあります。busyboxは単一の実行ファイルで、呼び出されたときのコマンド名に応じて様々なコマンドの動作が可能な特殊なソフトウェアです。もちろんnl
の機能も内包されています。実行ファイルのサイズがとても小さいので、組み込み機器など記憶領域に制約がある環境で採用されています。
種類やバージョンの調べ方
--versionオプション
--version
オプションでコマンドのバージョンを見ることができます。このとき著作権に関する情報も出力されるので、どんなnl
なのかを知ることができます。しかしcoreutils以外のnl
の実装では、--version
オプションに対応しておらずエラーと簡単な使い方だけが表示されてバージョンが判明しないこともあります。
$ nl --version
nl (GNU coreutils) 8.30
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Written by Scott Bartram and David MacKenzie.
Ubuntuのnl
では、--version
オプションを使うことで、GNU coreutilsであることがわかりました。
% nl --version
nl: illegal option -- -
usage: nl [-p] [-b type] [-d delim] [-f type] [-h type] [-i incr] [-l num]
[-n format] [-s sep] [-v startnum] [-w width] [file]
一方macOSのnl
では、--version
オプションをサポートしていないので、一意に識別することはできません。
Manpage
Manpageの記述を見ることでも、nl
の種類を判断することができます。Manpageが存在しない環境では表示されませんが、ほとんどのLinuxやmacOSで表示できるはずです。man nl
と実行すればnl
のManpageを読むことができます。著作権やバージョンの記述は下の方に記載されていますので、tail
を用いて最後の10行を表示してみましょう。
$ man nl | tail -n 10
Copyright © 2018 Free Software Foundation, Inc. License GPLv3+: GNU
GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
SEE ALSO
Full documentation at: <https://www.gnu.org/software/coreutils/nl>
or available locally via: info '(coreutils) nl invocation'
GNU coreutils 8.30 September 2019 NL(1)
こちらを見てもUbuntuのnl
はcoreutilsであることが確認できました。
% man nl | tail -n 10
STANDARDS
The nl utility conforms to IEEE Std 1003.1-2001 (``POSIX.1'').
HISTORY
The nl utility first appeared in AT&T System V Release 2 UNIX.
BUGS
Input lines are limited to LINE_MAX (2048) bytes in length.
BSD January 26, 2005 BSD
macOSはManpageのフッターを見ることで、BSD系のnl
であることが確認できました。
コマンドの識別
コマンドは絶対パスではなくコマンド名だけで呼び出すことがほとんどです。しかし一つの環境で複数のnl
がインストールされている場合など、どのコマンドが呼び出されているのかわからなくなることがあります。このような場合にはwhich
を利用することで、デフォルトでどのコマンドが実行されているのかを調べることができます。
$ which nl
/usr/bin/nl
これで/usr/bin/nl
が実行されることがわかります。さらに詳細を知りたい場合は、先ほどの例にならい/usr/bin/nl --version
を実行してバージョンなどを調べてみると良いでしょう。
実行されるコマンドはシェルの環境変数である$PATH
に基づいて選ばれています。詳しくは説明しませんが、この環境変数を変更することで、実行するデフォルトのコマンドを変更することができます。
補足
この記事シリーズでは特に断りのない限り、GNU coreutilsのnl
を使用します。
macOSでcoreutilsのnl
を利用したい場合は、brew
などを利用してインストールできます。デフォルトではgnl
という名前のコマンドとしてインストールされ、もとのBSD系のnl
と使い分けることができます。他のcoreutilsのコマンドも頭にg
をつければ使うことができます。
% brew install coreutils
(略)
% gnl --version
(略)