コマンド実行時のエラーメッセージを大幅に改良
uutils coreutils 0.11.0 で、コマンド実行時のエラーメッセージが大幅に改良されました。エラー箇所を特定しやすくなった
コマンド実行時にエラーが発生した時に、stderr(標準エラー)にエラーメッセージが出力されます。このエラーメッセージが rustc(Rust コンパイラー)のように、具体的に問題のあった箇所とその問題の内容を出力するようになりました。
今回28種のコマンドでエラーメッセージが改良されています。
tr コマンドの例
tr コマンドでは、ユーザーが既に照合順序を把握していることを前提にしています。そのため照合順序を間違えると、以下のようにエラーメッセージが出力されていました。
$ tr 'qw[y-b]' x
tr: range-endpoints of 'y-b' are in reverse collating sequence order
tr: range-endpoints of 'y-b' are in reverse collating sequence order
これが以下のように出力されるようになりました。
$ tr 'qw[y-b]' x
tr: range-endpoints of 'y-b' are in reverse collating sequence order
╭─[ tr:1:7 ]
│
1 │ tr qw[y-b] x
│ ─┬─
│ ╰─── did you mean 'b-y'?
│
│ Help: a range goes from the lower character to the higher one, as in a-z
───╯
tr: range-endpoints of 'y-b' are in reverse collating sequence order
╭─[ tr:1:7 ]
│
1 │ tr qw[y-b] x
│ ─┬─
│ ╰─── did you mean 'b-y'?
│
│ Help: a range goes from the lower character to the higher one, as in a-z
───╯
cut コマンドの例
cut コマンドでは、長いリストの中に1つだけ問題のあるリスト要素を指定してしまうことがあります。例えば範囲指定を間違えると、以下のようにエラーメッセージが出力されていました。
$ cut -f 1,4-2,9-12 notes.txt
cut: invalid decreasing range
Try 'cut --help' for more information.
cut: invalid decreasing range
Try 'cut --help' for more information.
これが以下のように出力されるようになりました。
$ cut -f 1,4-2,9-12 notes.txt
cut: invalid decreasing range
╭─[ cut:1:10 ]
│
1 │ cut -f 1,4-2,9-12 notes.txt
│ ─┬─
│ ╰─── this range ends before it starts
│
│ Help: a list is N, N-M, N- or -M, separated by commas, as in -f1,4-6,9-
───╯
Try 'cut --help' for more information.
cut: invalid decreasing range
╭─[ cut:1:10 ]
│
1 │ cut -f 1,4-2,9-12 notes.txt
│ ─┬─
│ ╰─── this range ends before it starts
│
│ Help: a list is N, N-M, N- or -M, separated by commas, as in -f1,4-6,9-
───╯
Try 'cut --help' for more information.
chmod の例
例えば chmod コマンドで以下のようにオプションの指定を間違えると、今までは以下のようにエラーメッセージが出力されていました。$ chmod 'g+rw?x' notes.txt
chmod: invalid operator (expected +, -, or =, but found ?)
chmod: invalid operator (expected +, -, or =, but found ?)
しかし以下のようにキャレットで問題箇所の1文字を指定して出力されるようになりました。
$ chmod 'g+rw?x' notes.txt
chmod: invalid operator (expected +, -, or =, but found ?)
╭─[ chmod:1:5 ]
│
1 │ g+rw?x notes.txt
│ ─
│
│ Help: a mode is either octal, as in 644, or clauses such as u+rwx,go-w
───╯
chmod: invalid operator (expected +, -, or =, but found ?)
╭─[ chmod:1:5 ]
│
1 │ g+rw?x notes.txt
│ ─
│
│ Help: a mode is either octal, as in 644, or clauses such as u+rwx,go-w
───╯
sort コマンドの例
sort コマンドで指定するキーに余計な文字が1つ紛れ込んでいても、気づけないことがあります。例えばフィールド指定を間違えると、以下のようにエラーメッセージが出力されていました。
$ sort -k2.3x notes.txt
sort: stray character in field spec: invalid field specification '2.3x'
sort: stray character in field spec: invalid field specification '2.3x'
これが以下のように出力されるようになりました。
$ sort -k2.3x notes.txt
sort: stray character in field spec: invalid field specification '2.3x'
╭─[ sort:1:11 ]
│
1 │ sort -k2.3x notes.txt
│ ─
│
│ Help: a key is FIELD[.CHAR][OPTS][,FIELD[.CHAR][OPTS]], as in -k2.3,4nr
───╯
sort: stray character in field spec: invalid field specification '2.3x'
╭─[ sort:1:11 ]
│
1 │ sort -k2.3x notes.txt
│ ─
│
│ Help: a key is FIELD[.CHAR][OPTS][,FIELD[.CHAR][OPTS]], as in -k2.3,4nr
───╯
env -S コマンドの例
env -S はコマンドライン全体を受け取り、シェルと同じような方法で解釈します。従来のエラーメッセージでは、問題のあった部分を断片的に表示していました。
$ env -S 'echo ${1FOO}'
env: only ${VARNAME} expansion is supported, error at: ${1FOO}
env: only ${VARNAME} expansion is supported, error at: ${1FOO}
この文字列にはスペースが含まれているため、表示するときには引用符で囲まれます。
しかし引用符の内側であっても、キャレットは問題の箇所を正しく指してエラーメッセージを出力します。
$ env -S 'echo ${1FOO}'
env: only ${VARNAME} expansion is supported, error at: ${1FOO}
╭─[ env:1:14 ]
│
1 │ env -S 'echo ${1FOO}'
│ ─┬─
│ ╰─── a variable name cannot start with a digit
│
│ Help: only $NAME and ${NAME} are expanded; the other shell forms are not
───╯
env: only ${VARNAME} expansion is supported, error at: ${1FOO}
╭─[ env:1:14 ]
│
1 │ env -S 'echo ${1FOO}'
│ ─┬─
│ ╰─── a variable name cannot start with a digit
│
│ Help: only $NAME and ${NAME} are expanded; the other shell forms are not
───╯
test コマンドの例
test コマンドは複数の引数から式を組み立てます。式の指定を間違えると、以下のようにエラーメッセージが出力されていました。
$ test 7 -eq zap
test: invalid integer 'zap'
test: invalid integer 'zap'
これが以下のように出力されるようになりました。
$ test 7 -eq zap
test: invalid integer 'zap'
╭─[ test:1:7 ]
│
1 │ 7 -eq zap
│ ───
│
│ Help: -eq, -ne, -lt, -le, -gt and -ge compare integers; use =, !=, < or > to compare strings
│ -eq equal, -ne not equal, -lt less than, -le less than or equal, -gt greater than, -ge greater than or equal
───╯
test: invalid integer 'zap'
╭─[ test:1:7 ]
│
1 │ 7 -eq zap
│ ───
│
│ Help: -eq, -ne, -lt, -le, -gt and -ge compare integers; use =, !=, < or > to compare strings
│ -eq equal, -ne not equal, -lt less than, -le less than or equal, -gt greater than, -ge greater than or equal
───╯
サイズと単位の指定ミス
例えばバイトサイズを指定する際、数値とその単位を指定できるケースがあります。例えば head コマンドでサイズ指定を間違えると、以下のようにエラーメッセージが出力されていました。
$ head -c 1fb notes.txt
head: invalid number of bytes: '1fb'
head: invalid number of bytes: '1fb'
これが以下のように出力されるようになりました。
$ head -c 1fb notes.txt
head: invalid number of bytes: '1fb'
╭─[ head:1:10 ]
│
1 │ head -c 1fb notes.txt
│ ─┬
│ ╰── not a known unit
│
│ Help: a size is a number and an optional unit: K, M, G and so on for 1024, KB, MB, GB for 1000
───╯
head: invalid number of bytes: '1fb'
╭─[ head:1:10 ]
│
1 │ head -c 1fb notes.txt
│ ─┬
│ ╰── not a known unit
│
│ Help: a size is a number and an optional unit: K, M, G and so on for 1024, KB, MB, GB for 1000
───╯
以下のように他にもサイズを指定できるコマンドはありますが、サイズの解釈は同じパーサーを用いて解釈されるため、同じミスについては同じエラーメッセージフォーマットで出力されます。
- tail -c
- truncate -s
- split -b
- shred -s
- od -N
- sort -S
- du -B
- df -B
- ls --block-size のブロックサイズ指定
- du -t のしきい値指定
numfmt コマンドの例
numfmt --format は printf 形式のフォーマットに対応していますが、変換指定を間違えた時に、以下のようなエラーメッセージが出力されていました。$ numfmt --format=%q 1000
numfmt: invalid format '%q', directive must be %[0]['][-][N][.][N]f
numfmt: invalid format '%q', directive must be %[0]['][-][N][.][N]f
これが以下のように出力されるようになりました。
$ numfmt --format=%q 1000
numfmt: invalid format '%q', directive must be %[0]['][-][N][.][N]f
╭─[ numfmt:1:18 ]
│
1 │ numfmt --format=%q 1000
│ ┬
│ ╰── f is the only conversion numfmt has; %d, %e, %g and the other C conversions are not accepted
│
│ Help: a format is [PREFIX]%[0]['][-][WIDTH][.PRECISION]f[SUFFIX], as in "%'-10.2f"
───╯
numfmt: invalid format '%q', directive must be %[0]['][-][N][.][N]f
╭─[ numfmt:1:18 ]
│
1 │ numfmt --format=%q 1000
│ ┬
│ ╰── f is the only conversion numfmt has; %d, %e, %g and the other C conversions are not accepted
│
│ Help: a format is [PREFIX]%[0]['][-][WIDTH][.PRECISION]f[SUFFIX], as in "%'-10.2f"
───╯
csplit コマンドの例
csplit コマンドに指定するパターンでは、正規表現を利用できます。正規表現にミスがあった時に、以下のようなエラーメッセージが出力されていました。
$ csplit notes.txt '/a{2,1}/'
csplit: '/a{2,1}/': invalid pattern
csplit: '/a{2,1}/': invalid pattern
これが以下のように出力されるようになりました。
$ csplit notes.txt '/a{2,1}/'
csplit: '/a{2,1}/': invalid pattern
╭─[ csplit:1:20 ]
│
1 │ csplit notes.txt /a{2,1}/
│ ──┬──
│ ╰──── invalid repetition count range, the start must be <= the end
│
│ Help: a pattern is a line number N, /REGEXP/[OFFSET] or %REGEXP%[OFFSET], each optionally followed by {N} or {*}
───╯
csplit: '/a{2,1}/': invalid pattern
╭─[ csplit:1:20 ]
│
1 │ csplit notes.txt /a{2,1}/
│ ──┬──
│ ╰──── invalid repetition count range, the start must be <= the end
│
│ Help: a pattern is a line number N, /REGEXP/[OFFSET] or %REGEXP%[OFFSET], each optionally followed by {N} or {*}
───╯
互換性の維持
今回エラーメッセージが大幅に改良され、レポート形式でエラー内容が出力されるようになりましたが、GNU coreutils との互換性は崩れていません。stderr とターミナル
改良されたエラーメッセージは、stderr がターミナルに接続されている場合のみ出力されるようになっています。スクリプトやパイプといった処理では、改良前の1行形式のエラーメッセージがそのまま出力されます。
そのため stderr に対して grep を行っている処理があっても、引き続きそのまま動作します。
終了コード
コマンド実行後の終了コードの変更もありません。有効・無効の切り替え
デフォルトでは stderr がターミナルに接続されている場合のみ、レポート形式でエラーを出力します。通常はこの判定方法及び利用方法で問題ありませんが、レポート形式でのエラー出力を意図的に指定することもできます。
UUTILS_DIAG 環境変数
レポート形式でのエラー出力は、UUTILS_DIAG 環境変数で制御できます。| 値 | 説明 |
|---|---|
| always | スクリプトやパイプといった処理でも、 常にレポート形式でエラーを出力 |
| never | 常にレポート形式でエラーを出力しない |
| auto / 指定なし |
stderr がターミナルに接続されているかどうかで判断する。 デフォルトの動作 |
活用例
スクリプトや CI ログでレポート形式のエラーメッセージが必要な場合は、この制御を利用して以下のようにファイルに出力する方法もあります。$ UUTILS_DIAG=always sort -k2.3x notes.txt 2> parse.log
$ cat parse.log
sort: stray character in field spec: invalid field specification '2.3x'
╭─[ sort:1:11 ]
│
1 │ sort -k2.3x notes.txt
│ ─
│
│ Help: a key is FIELD[.CHAR][OPTS][,FIELD[.CHAR][OPTS]], as in -k2.3,4nr
───╯
$ cat parse.log
sort: stray character in field spec: invalid field specification '2.3x'
╭─[ sort:1:11 ]
│
1 │ sort -k2.3x notes.txt
│ ─
│
│ Help: a key is FIELD[.CHAR][OPTS][,FIELD[.CHAR][OPTS]], as in -k2.3,4nr
───╯
コマンドラインオプションでの指定不可
レポート形式でのエラー出力を制御するようなコマンドラインオプションは提供されていません。新しいオプションを追加すると不正な指定になったり、オペランドそのものと区別できず曖昧な表現になってしまい兼ねないためです。
カラーコードの制御
エラーメッセージに色を指定するカラーコードも制御可能です。カラーコードの出力もターミナルに接続されている場合のみ有効になります。
