Bash の特集変数 $_ を使って変数定義を省略する

2022-08-05Bash

はじめに

先日、他の方が作成されたスクリプトを拝見していたときに見つけた特殊変数 $_ があまり見慣れないものだったので、調べて見ました。

検証環境

$ uname -moi
aarch64 aarch64 GNU/Linux

$ head -n 2 /etc/os-release
PRETTY_NAME="Ubuntu Kinetic Kudu (development branch)"
NAME="Ubuntu"

$ bash -version | head -n 1
GNU bash, バージョン 5.1.16(1)-release (aarch64-unknown-linux-gnu)

スクリプトで使われていた $_ 特殊変数について

Bash では 全ての引数を表す $@引数の数を表す $#  、 実行中のプロセス ID を表す $$ など、いくつか組み込み機能として提供されている変数があります。

$_ はそういった変数のうちの 1 つになります。

では、 $_ はどのような変数なのでしょうか。

$_  変数は「直前に実行されたコマンドの最後の引数」を表す

$_  変数は「直前に実行されたコマンドの最後の引数」を表します。

早速具体的な例を見ていきましょう。

$_ 変数が利用されていたコードは以下のようなものになっていました。

$ mkdir hoge && cd "$_"

こちらの命令を実際に実行してみたいと思います。

実行前、実行後にカレントディレクトリを出力してみます。

$ pwd
/workdir

# hoge/ ディレクトリを作成し、 `$_` の指し示すディレクトリに移動
$ mkdir hoge && cd "$_"

$ pwd
/workdir/hoge

こちらのコードからわかるのは、 $_hoge を示しているということです。
値を出力くしてみましょう。

$ mkdir hoge

$ echo $_
hoge

確かに $_hoge という値を示しています。

$_ は、直前に実行されたコマンドの引数を表す変数であることがわかります

もう一つ実験してみます。
直前に実行されたコマンドの引数が複数だった場合はどのような挙動になるでしょう?

$ echo aa bb cc
aa bb cc

$ echo $_
cc

aa / bb / cc の 3 つの引数のうち、最後の引数 cc の値だけが格納されていることがわかりました。

$_ は、直前に実行されたコマンドの最後の引数を表す変数であることがわかります

ちょっとしたコマンドの連続であれば登場する変数を減らすことができる

$_ をうまく使えば、変数を上手にへらすことができます。

例えば以下のような操作を想定してみます。

  1. ディレクトリを作成
  2. 作成したディレクトリに移動
  3. git init して Git ワークスペースとして初期化

$_ 変数を使わない場合、以下のように記述することができます。

$ REPO_NAME=hello

$ mkdir $REPO_NAME

$ cd $REPO_NAME

$ git init
Initialized empty Git repository in /Users/genzouw/hello/.git/

$_ 変数を使うことで、以下のように記述することができます。

$ mkdir hello

$ cd $_

$ git init
Initialized empty Git repository in /Users/genzouw/hello/.git/

ステップ、変数ともに減らすことができました。

ひとこと

$_ 変数は便利ではありますが、事前に知識が必要になるため、万人向けのスクリプトを想定すると可読性が高いとは言えません。
使い所に注意が必要ですね。

2022-08-05Bash