0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

nlコマンドの細かい仕様を調べていくと最大値や最小値も気になりますね。実装ごとの仕様やエラーについてまとめておこうと思います。

行番号

つまり何行まで数えられるかということです。BSD系のnlではデフォルトの桁数がボトルネックになることは以前も確認しましたが、今回は「行数」の最大値を見ていきます。また、x86_64(AMD64)のアーキテクチャで検証していますので、環境によっては異なる可能性もあると思います。

GNU coreutils

coreutils~v8.32
$ yes unko | nl -v 9223372036854775806
9223372036854775806	unko
9223372036854775807	nl: line number overflow

coreutilsのnlでは符号付き64bitのようです。9,223,372,036,854,775,807が最大値と言いたいところですが、厳密にはunkoを出し切らずにオーバーフローでエラーになっています。しかしこの中途半端なエラーも2020年10月の修正のついでに改善されているので、次版(v8.33?)以降では最後まで出し切ってからエラーになります。

coreutils-next
$ yes unko | nl -v 9223372036854775806
 9223372036854775806	unko
 9223372036854775807	unko
 nl: line number overflow

どの行でオーバーフローしたのかが明確になるので、少々デバッグが楽になるんじゃないかと思います。900京行超えのテキストファイルなんて絶対触りたくないですけどね。

BSD系

BSD(macOS)
$ yes unko | nl -v 2147483647 -w 11 | head -2
 2147483647	unko
-2147483648	unko

BSD系のnlでは符号付き32bitのようです。つまり2,147,483,647が最大です。
そしてオーバーフローしません。そのまま符号がひっくり返ってカウントを続けます。つまり正しい行番号を出力しませんが、エラーが発生して終了することもありません。

busybox

busyboxはちょっとおもしろい挙動です。また、負の値には対応していません。

busybox
$ yes unko | busybox nl -v 2147483648 | head
nl: number 2147483648 is not in 0..2147483647 range

オプションに大きな数を指定するとエラーになります。符号付き32bitの正の値だけが有効のようです。しかし、実際に使ってみると上限はほかのところにあります。

$ yes unko | busybox nl -v 2147483647 | head -n 2147483647 | tail
4294967284	unko
4294967285	unko
4294967286	unko
4294967287	unko
4294967288	unko
4294967289	unko
4294967290	unko
4294967291	unko
4294967292	unko
4294967293	unko

あまり厳密ではありませんが(回しっぱなしにしてみたら超時間かかったのでやり直したくない)、符号なし32bitまではカウントできるようです。

変数の型を確認する

実行が中途半端になってしまったので、代わりにbusyboxのソースを確認しましょう。
まずは、-vオプションの引数処理です。
https://github.com/mirror/busybox/blob/master/coreutils/nl.c


	getopt32long(argv, "pw:+s:v:+i:+b:", nl_longopts,
			&ns.width, &ns.sep, &ns.start, &ns.inc, &opt_b);

pw:+s:v:+i:+b:v:+という部分が、-vの識別子ですね。
https://github.com/mirror/busybox/blob/master/libbb/getopt32.c


 "o:+"  This means that the parameter for this option is a nonnegative integer.
        It will be processed with xatoi_positive() - allowed range
        is 0..INT_MAX.

こちらを確認すると、:+0..INT_MAXということのようです。

あとは行番号の処理も見ましょう。ちなみにbusyboxではこの処理はcat -nと共通です。
https://github.com/mirror/busybox/blob/master/libbb/print_numbered_lines.c

void FAST_FUNC print_numbered_lines(struct number_state *ns, const char *filename)
{
	FILE *fp = fopen_or_warn_stdin(filename);
	unsigned N = ns->start;

unsigned Nがカウンタの変数です。つまり、オプションを取得する関数内で正の数に制限されているだけで、カウンタ自体は2倍のunsignedまでカウントできるようです。

#エラー

もしシェルスクリプトなどでエラー処理を書く場合は、戻り値(終了ステータス)を見ることになります。bashでは戻り値が変数$?に格納されるので、それを確認することもできます。

POSIX

EXIT STATUS
The following exit values shall be returned:
0
Successful completion.
>0
An error occurred.

POSIXでは成功した場合は0、エラーは0より大きいと決められています。各実装でエラーのときどんな値が返ってくるのか見てみましょう。存在しないオプションを実行してみます。

GNU coreutils

coreutils
$ nl -a &>/dev/null || echo $?
1

busybox

busybox
$ busybox nl -a &>/dev/null || echo $?
1

BSD系

BSD(macOS)
$ nl -a &>/dev/null || echo $?
1

どれも1が返ってきました。


0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?