What’s New In Bash 5 ノート¶
Bash バージョン 5.x で追加された新機能のメモ。全部を追跡するのは無理だから気になるものと便利とされている機能を中心に拾っていく。
バージョン 5.0¶
Bash-5.0 release available からめぼしい項目に絞ってノートを取る。
There is an
EPOCHSECONDSvariable, which expands to the time in seconds since the Unix epoch.
例えばコマンド echo $EPOCHSECONDS を実行すると、コマンド date +%s と同じものを出力する。
There is an
EPOCHREALTIMEvariable, which expands to the time in seconds since the Unix epoch with microsecond granularity.
これも同様で、コマンド echo $EPOCHREALTIME を実行すれば date +%s.%6N と同じ出力が得られる。
BASH_ARGV0: a new variable that expands to$0and sets$0on assignment.
変数 $0 に値を代入することは不可能だが、それを可能にするのが変数
BASH_ARGV0 だ。デバッグ用途らしい。
history -dunderstands negative arguments: negative arguments offset from the end of the history list.
例えば history -d -10 とすれば、有効なコマンド履歴の十個前に実行したコマンドを履歴から削除する。
The
waitbuiltin now has a-foption, which signfies to wait until the specified job or process terminates, instead of waiting until it changes state.
コマンド wait -f ID はジョブ状態が変更されたときに返るのではなく、ジョブ
ID が実際に終了するのを待ってからその終了コードを返すようになる。
If a non-interactive shell with job control enabled detects that a foreground job died due to
SIGINT, it acts as if it received theSIGINT.
これは既存の何かに影響するか?
A new
shoptoption:localvar_inherit; if set, a local variable inherits the value of a variable with the same name at the nearest preceding scope.
次の関数で説明する。局所変数 var を内側の局所変数スコープとそのすぐ外側のスコープに宣言する。このオプションを有効にすると、局所変数スコープ突入前に同名の変数に値が初期化済みならば、その値を引き継ぐようになる。
function demo_localvar_inherit
{
    function outer
    {
        local var
        echo In call: $var
        var=localvar
        echo In call, after setting: $var
    }
    local var=globalvar
    echo Before call: $var
    outer
    echo After call: $var
}
オプションを変えて関数を呼んだ結果を比較する:
bash$ shopt -u localvar_inherit; demo_localvar_inherit
Before call: globalvar
In call:
In call, after setting: localvar
After call: globalvar
bash$ shopt -s localvar_inherit; demo_localvar_inherit
Before call: globalvar
In call: globalvar
In call, after setting: localvar
After call: globalvar
継承しないほうが、つまり従来と同じ設定のほうが変数のスコープの意味が生きるから好みだ。
The
historybuiltin can now delete ranges of history entries using-d start-end.
コマンド履歴を履歴番号範囲を指定することで削除できるようになった。次を実行するとコマンド履歴番号 1103 から 1118 までの履歴を削除する:
bash$ history -d 1103-1118
先ほど挙げた負のオフセットを start および end の値として受け入れる。例えば次のようなコマンドが考えられる:
 bash$ history -d -16--1
The command completion code now matches aliases and shell function names
case-insensitively if the readline ``completion-ignore-case`` variable is set.
ファイル $HOME/.inputrc で set completion-ignore-case on を指定しているはずだ。こうすると alias や function の名前補完にも効果があるようになった。これは便利なのかどうかわからない。その手の識別子には小文字しか使わないようにしている。
There is a new
assoc_expand_onceshell option that attempts to expand associative array subscripts only once.
これはなぜあるのだろう。
The
umaskbuiltin now allows modes and masks greater than octal 777.
要するに四桁のマスクを操作可能になったということか。
The
completebuiltin now accepts a-Ioption that applies the completion to the initial word on the line.
行の最初の単語に補完を適用することができるようになった。
The
localvar_inheritoption will not attempt to inherit a value from a variable of an incompatible type (indexed vs. associative arrays, for example).
新規オプション localvar_inherit に関する仕様の一部。型を指定して局所変数を宣言するデモを書いて試したいところだ。
The
globasciirangesoption is now enabled by default; it can be set to off by default at configuration time.
オプション globasciiranges 自体は以前からある。5.0 でこの既定値が on になったと言っている。例えば、パターン [a-d] が a, b, c, d のいずれかにマッチするパターンを意味するように指定したい場合(大文字などは不要)に有効にする。
Associative and indexed arrays now allow subscripts consisting solely of whitespace.
配列の添字が空白文字のみから構成されても構わないと読めるが、実際には先頭の要素が参照されるという理解でいいか?
checkwinsizeis now enabled by default.
このオプションは WSL が明示的に on にしているので気にしない。
The
localvar_unsetshoptoption is now visible and documented.
隠しオプション localvar_unset が表に浮上。
このオプションが on の場合、直前の関数スコープにある局所変数に対する unset
呼び出しが、その関数が戻るまでに後続の検索でそれらが未設定であることをわかるように印をつけるようになる。この挙動は現在の関数スコープでローカル変数の設定を解除したときのそれと同じだ。
The
progcomp_aliasshopt option is now visible and documented.
隠しオプション progcomp_alias が表に浮上。仕様を読むと alias が絡むダブル補完を試みると読める。
There is a new
seqloadable builtin.
手許の環境では存在しない。
The
$_variable doesn’t change when the shell executes a command that forks.
ではどうなるのか。
POSIX mode now enables the
shift_verboseoption.
コマンド shift で範囲外の数を指定すると、たいていのシェルではエラーとなる。しかし、本家 POSIX ではエラーとする仕様では特にない。Bash 5.0 からはこのオプション自体を有効にするようになった。そう解釈していいか。
バージョン 5.1¶
Bash-5.1 release available のめぼしい項目に集中してノートをつづる。
read -e may now be used with arbitrary file descriptors (read -u N).
Readline が効いた状態と descriptors を指定することが両立可能になった。
The
selectbuiltin now runs traps if its internal call to thereadbuiltin is interrupted by a signal.
組み込みコマンド select は、信号が read の内部呼び出しに割り込んだときにトラップするようになった。
SRANDOM: a new variable that expands to a 32-bit random number that is not produced by an LCRNG, and usesgetrandom/getentropy, falling back to/dev/urandomorarc4randomif available. There is a fallback generator if none of these are available.
環境変数 SRANDOM から 32 ビット長の乱数を得られる。ここに言及されているような手段、関数で生成されるため、srand のようなものを使って乱数列を再現することは不可能のようだ。
bash$ echo $SRANDOM
3687839026
bash$ echo $SRANDOM
1135571563
bash$ echo $SRANDOM
2451151285
shell-transpose-words: a new bindable readline command that uses the same definition of word asshell-forward-word, etc.The shell now adds default bindings for
shell-forward-word,shell-backward-word,shell-transpose-words, andshell-kill-word.
新コマンド shell-transpose-words の意味は直観的に理解できると思うので説明を省く(パス文字列などで transpose-words との違いを実感できる)。
ここで挙げたコマンドに対するキーバインド既定値は次のとおり:
| キーバインド | コマンド | 
|---|---|
| M-C-b | 
 | 
| M-C-d | 
 | 
| M-C-f | 
 | 
| M-C-t | 
 | 
If unset is executed without option arguments, bash tries to unset a shell function if a name argument cannot be a shell variable name because it’s not an identifier.
コマンド unset をオプションなしで実行すると、引数を変数名として処理することをまず試みる。それが失敗すると、今度は関数名として処理する。
The test -N operator uses nanosecond timestamp granularity if it’s available.
ファイルが最後に読み込まれてからナノ秒単位の短時間の間に変更されたとしてもテストが機能するようになった。
BASH_REMATCHis no longer readonly.
この環境変数は [[ target =~ pattern ]] テストの結果を格納する配列だ。その読み取りしかできない性質がなくなったということは?
wait: has a new
-p VARNAMEoption, which stores the PID returned by wait -n or wait without arguments.
コマンド wait 実行時にプロセス ID を保存しておく事態になったらこれを使おう。
Sorting the results of pathname expansion now uses byte-by-byte comparisons if two strings collate equally to impose a total order; the result of a POSIX interpretation.
それでもなお等しいということはあり得ないか。
Bash now allows
SIGINTtraphandlers to execute recursively.
これだけでは何のことかわからない。
Process substitution is now available in posix mode.
プロセス置換が POSIX モードで利用可能になったことは本バージョンの注目項目の一つとして紹介されている。
READLINE_MARK: a new variable available while executing commands bound with bind -x, contains the value of the mark.
変数 READLINE_MARK はコマンド bind -x で使用する Readline ラインバッファー内の印の位置を含む変数だ。挿入点と印の間の文字列が region と呼ばれるものだ。
test -v N can now test whether or not positional parameter
Nis set.
$1, $2, … がセット済みかどうかを知る術は他にもある。
localnow honors the-poption to display all local variables at the current context.
今まで知らなかったが、実は local はシェル関数であったのだ。キーワードかと思っていた。何らかの関数中で local -p を呼び出すと、上述のように機能する。
function test-local {
    local a=3
    local b=Mono
    echo test local
    local -p
}
実行結果の例(この出力と一致しない場合があり得る):
bash$ test-local
test local
declare -- a="3"
declare -- b="Mono"
The
@avariable transformation now prints attributes for unset array variables.The
@Avariable transformation now prints a declare command that sets a variable’s attributes if the variable has attributes but is unset.
やってみよう:
bash$ declare -a myarray
bash$ echo ${myarray@a}
a
bash$ echo ${myarray@A}
declare -a myarray
declareandlocalnow have a-Ioption that inherits attributes and value from a variable with the same name at a previous scope.
これは入れ子スコープで変数を複製するのに利用できるだろうか。
When run from a
-ccommand,jobsnow reports the status of completed jobs.
コマンド jobs を bash -h 中に実行するとジョブの実行状況を確認できる。
New
U,u, andLparameter transformations to convert to uppercase, convert first character to uppercase, and convert to lowercase, respectively.
変数変換 ${parameter@operator} において、operator 部分にこれらの記号が対応された。それぞれの変換は Emacs における upcase-word, capitalize-word,
lowercase-word に相当すると憶えておくといい。
myvar=varName
bash$ echo ${myvar@u} ${myvar@U} ${myvar@L}
VarName VARNAME varname
PROMPT_COMMAND: can now be an array variable, each element of which can contain a command to be executed like a stringPROMPT_COMMANDvariable.
変数 PROMPT_COMMAND は PS1 を表示する前に毎回実行されるコマンドを指定するものだ。複数のコマンドを実行するために配列を代入することが可能になった。例えば
PROMPT_COMMAND=( "command1" "command2" ... )
とすると、端末でコマンドを何か入力、実行するたびに command1, command2, …がいちいち実行されるようになる。
ulimit has a
-Roption to report and set theRLIMIT_RTTIMEresource.
コマンド ulimit 自体を全く利用しないので後回し。
Associative arrays may be assigned using a list of key-value pairs within a compound assignment. Compound assignments where the words are not of the form
[key]=valueare assumed to be key-value assignments. A missing or empty key is an error; a missing value is treated asNULL. Assignments may not mix the two forms.
連想配列への key-value の代入および追加方法が次のような式が合法になるように拡張された:
bash$ declare -A mymap=(k0 v0 k1 v1)
bash$ echo "${mymap[@]}"
v0 v1
bash$ mymap+=(k2 v2 k3 v3)
bash$ echo "${mymap[@]}"
v0 v1 v2 v3
New
Kparameter transformation to display associative arrays as key-value pairs.
連想配列の値を引用符で囲まれた可能性のある出力を生成する。先ほどの例の mymap
に適用すると:
echo "${mymap[@]@K}"
k0 "v0" k1 "v1" k2 "v2" k3 "v3"
SECONDSandRANDOMmay now be assigned using arithmetic expressions, since they are nominally integer variables.LINENOis not an integer variable.
そのようなことはしない。
Bash temporarily suppresses the verbose option when running the
DEBUGtrap while running a command from the fc builtin.
状況がわからない。
wait -n now accepts a list of job specifications as arguments and will wait for the first one in the list to change state.
オプションの -n は the next の意。この変更は理に適っている。
HISTFILEis now readonly in a restricted shell.
制限シェル rbash を起動して変数の属性を先ほど習った変数展開で調べる:
bash$ echo ${HISTFILE@a}
r
GLOBIGNOREnow ignores.and..as a terminal pathname component.
環境変数 GLOBIGNORE はコロン区切りのパターンのリストであって、パス展開時に無視されるパターンを定義する。Bash 5.1 からはドットおよびドットドットが端末パス名構成要素としては無視されるようになったと言っている。
バージョン 5.2¶
Todo
現在利用している Ubuntu 22.04.2 LTS の Bash はバージョンが 5.1 だ。本節以降を記すのは Ubuntu をアップグレードしてバージョンが 5.2 以上になってからとする。
参考資料¶
- Bash 5.0 is here with new features and improvements | Packt Hub 
- upgrade - What’s going to be new in bash 5 - Unix & Linux Stack Exchange 
- Get current time in seconds since the Epoch on Linux, Bash - Stack Overflow 
- variable - What is the purpose of BASH_ARGV0 in bash? - Unix & Linux Stack Exchange 
- scope - Bash: Hide global variable using local variable with same name - Stack Overflow 
- linux - How to delete history of last 10 commands in shell? - Stack Overflow 
- Bash 5.1 has already been released and these are its news | Linux Addicts 
- bash - Is $PROMPT_COMMAND a colon-separated list? - Unix & Linux Stack Exchange 
- その他、Bash Reference Manual やヘルプなど