Bash

提供: ArchWiki
2023年6月28日 (水) 03:18時点におけるKgx (トーク | 投稿記録)による版 (他言語へのリンクを修正)
ナビゲーションに移動 検索に移動

関連記事

Bash (Bourne-again Shell) は GNU プロジェクトによるコマンドラインシェル・プログラミング言語です。Bash という名前は先祖の名前のオマージュから来ています: 長い間非推奨であった Bourne shell です。Bash は GNU/Linux を含む様々な UNIX ライクなオペレーティングシステムで動作します。

Bash は、ArchLinux のデフォルトのコマンドラインシェルです。

実行

Bash は、起動の仕方によって動作が変わります。以下、それぞれのモードについて説明します。

Bash が TTY や SSH デーモンなどの login によって起動された場合、ログインシェル とみなされます。このモードは -l/--login コマンドラインオプションを使っても実行することができます。

Bash は、標準入力、標準出力、標準エラーが端末に接続されており (例えば、端末エミュレータで実行した場合)、 -c オプションまたは 非オプション 引数 (bash script のような) で開始しない場合は インタラクティブシェル と見なされます。すべての対話型シェルは /etc/bash.bashrc~/.bashrc をソースとし、対話型の ログイン シェルは /etc/profile~/.bash_profile もソースとしています。

ノート: Arch では、/bin/sh (以前は Bourne シェルの実行ファイルでした) は /bin/bash にシンボリックリンクされています。Bash が sh という名前で起動された場合、POSIX 互換性を含む、過去のバージョンの sh の起動時の動作を模倣しようとします。

設定ファイル

ファイル 説明 ログインシェル (注) インタラクティブ, non-login シェル
/etc/profile Source のアプリケーションの設定を /etc/profile.d/*.sh/etc/bash.bashrc に記述しています。 Yes No
~/.bash_profile ユーザーごとに、/etc/profile の後に表示されます。このファイルが存在しない場合、~/.bash_login~/.profile の順にチェックされます。また、隠しファイル /etc/skel/.bash_profile~/.bashrc のソースにもなっています。 Yes No
~/.bash_logout ユーザー単位で、ログインシェルが終了した後。 Yes No
/etc/bash.bash_logout コンパイルフラグ -DSYS_BASH_LOGOUT="/etc/bash.bash_logout" に依存します。ログインシェルの終了後。 Yes No
/etc/bash.bashrc -DSYS_BASHRC="/etc/bash.bashrc" コンパイルフラグに依存します。ソースは /usr/share/bash-completion/bash_completion です。 No Yes
~/.bashrc ユーザー単位で /etc/bash.bashrc の後に。 No Yes
ノート:
  • ログインシェルは --login 引数で呼び出すと非インタラクティブになります。
  • インタラクティブな非ログインシェルは ~/.bash_profile をソースとしませんが、親プロセス (ログインシェルかもしれません) の環境を継承しています。詳しくは ProcessManagement#On processes, environments and inheritance をご覧下さい。

シェルと環境変数

Bash とそれによって実行されるプログラムの動作は、多くの環境変数の影響を受ける可能性があります。環境変数 は、コマンドの検索ディレクトリや使用するブラウザなどの有用な値を格納するために使用されます。新しいシェルまたはスクリプトが起動されると、親の変数を継承するため、シェル変数の内部セットから開始されます [1]

この Bash のシェル変数は、エクスポートすることで環境変数にすることができます。:

VARIABLE=content
export VARIABLE

もしくはショートカットを使って:

export VARIABLE=content

環境変数は、他の Bash 互換のシェルが使用できるように、慣習的に ~/.profile または /etc/profile に置かれます。

詳しくは 環境変数 を参照してください。

コマンドライン

Bash のコマンドラインは Readline という名前の別のライブラリによって処理されています。Readline にはコマンドラインを使用するための多数のショートカットがあります。単語ごとに前後に移動、単語の削除など。また、入力したコマンドの履歴を管理するのも Readline の仕事です。最後に、また重要なことですが、Readline はマクロを作成するのを可能にします。

タブ補完

タブ補完Tab を複数回押すことによって途中まで入力したコマンドを自動で補完するオプションです (デフォルトで有効)。

シングルタブ機能

コマンドの補完を全て表示するにはタブを最大3回押す必要があります。タブを押す回数を減らしたい場合は Readline#高速な補完を読んでください。

プログラムとオプションを追加

デフォルトでは、Bash が補完するのはコマンドとファイル名、変数だけです。bash-completion パッケージをインストールすると一般的によく使われるコマンドやオプションのタブ補完も追加されます。bash-completion をインストールした場合、($ ls file.*<tab><tab> などの) 通常の補完も変わりますが、$ compopt -o bashdefault program で元に戻すことができます (詳しくは [2][3] を参照)。

プログラムとオプションを手動で追加

ノート: complete を使用すると bash-completion と衝突する可能性があります。

デフォルトでは Bash はコマンドの後のファイル名しか補完しません。complete -c を使うことでコマンド名も補完するようにできます:

~/.bashrc
complete -c man which

もしくはコマンド名とファイル名を補完するには -cf を使用:

complete -cf sudo

詳しくは Bash の man ページを見てください。

履歴

履歴の補完

履歴補完は矢印キー (下と上) で使うことができます (参照: Readline#履歴Readline Init File Syntax):

~/.bashrc
 bind '"\e[A": history-search-backward'
 bind '"\e[B": history-search-forward'

Readline プログラム全てに適用するには:

~/.inputrc
"\e[A": history-search-backward
"\e[B": history-search-forward

履歴を短くする

HISTCONTROL 変数を使うことで履歴に特定のコマンドが記録されないようにできます。例えば、同じコマンドが重複して記録されないようにするには:

~/.bashrc
export HISTCONTROL=ignoredups

erasedups に設定すると (コマンドが実行された順番と関係なく) Bash の履歴に同じコマンドが含まれないようになります。詳しくは Bash の man ページを見てください。

履歴を無効にする

bash の履歴を一時的にだけ無効にする場合。

$ set +o history

現在、入力されたコマンドは $HISTFILE に記録されません。

例えば、 printf secret | sha256sum でパスワードをハッシュ化したり、 gpg -eaF secret-pubkey.asc で GPG の使用を隠したりすることができるようになりました。 秘密はディスクに書き込まれません。

履歴を有効にするには

$ set -o history
ヒント: HISTCONTROL 変数に ignorespace が含まれている場合、スペースで始まるコマンドは履歴ファイルに保存されません。詳しくは bash(1) § Shell Variables を参照してください。

bash の履歴を全て無効にするには

~/.bashrc or /etc/profile
export HISTSIZE=0

...そして、念のため、古いヒストファイルを破棄してください。

$ wipe -i -l2 -x4 -p4 "$HISTFILE"
$ ln -sv /dev/null "$HISTFILE"

Zsh の run-help 機能

Zsh では Alt+h を押すことで入力したコマンドのマニュアルを呼び出すことができます。Readline の bind を使うことで Bash でも同じように使えます:

~/.bashrc
run-help() { help "$READLINE_LINE" 2>/dev/null || man "$READLINE_LINE"; }
bind -m vi-insert -x '"\eh": run-help'
bind -m emacs -x     '"\eh": run-help'

上記では (デフォルトの) Emacs 編集モード を使用していることを前提としています。

エイリアス

alias は特定の単語を別の文字列で置き換えるコマンドです。システムコマンドを短縮したり、日頃使っているコマンドにデフォルトの引数を追加するのに使用します。

個人的なエイリアスはなるべく ~/.bashrc に保存し、システム全体の (全てのユーザーに影響を与える) エイリアスは /etc/bash.bashrc に記述します。エイリアスの例は [4] を見てください。

関数については、Bash/関数を参照。

ヒントとテクニック

プロンプトのカスタマイズ

Bash/プロンプトのカスタマイズを見てください。

シンタックスハイライトとオートサジェスト機能

ble.sh は Readline を置き換える、純粋な Bash で書かれたコマンドラインエディタです。シンタックスハイライト、オートサジェスト、メニュー補完、略語、Vim 編集モード、フック関数など、多くの拡張機能を備えています。

インストール後、対話型セッションで Source を実行してください。設定は ~/.blerc ファイルと wiki で詳しく説明されています。

command not found

pkgfile には "command not found" フックが含まれており、認識できないコマンドを入力すると、自動的に公式リポジトリを検索します。

このフックを有効にするには、例えば以下のように source する必要があります。

~/.bashrc
source /usr/share/doc/pkgfile/command-not-found.bash

その後、利用できないコマンドを実行しようとすると、次のような情報が表示されます。

$ abiword
abiword may be found in the following packages:
  extra/abiword 3.0.1-2	/usr/bin/abiword
ノート: 動作させる前に、pkgfileデータベースを更新する必要があるかもしれません。 詳しくは pkgfile#Installation を参照してください。

代替の "command not found" フックは command-not-foundAUR で提供されており、以下のようになります。

$ abiword
The command 'abiword' is provided by the following packages:
abiword (2.8.6-7) from extra
	[ abiword ]
abiword (2.8.6-7) from staging
	[ abiword ]
abiword (2.8.6-7) from testing
	[ abiword ]

ターミナルで Ctrl+z を無効化

コマンドを以下のようにすることで Ctrl+z 機能 (アプリケーションの停止/終了) を無効化できます:

#!/bin/bash
trap "" 20
adom

これで adomAURShift+z の代わりに間違って Ctrl+z を押してしまっても Ctrl+z は無視されるため何も起こりません。

ログアウト後に画面をクリア

仮想コンソールでログアウト後に画面を消去するには:

~/.bash_logout
clear
reset

パスを入力したら自動で "cd"

シェルにパスだけを入力したとき Bash に cd を自動で前につけるようにすることができます。例えば通常は以下のようになりますが:

$ /etc
bash: /etc: Is a directory

.bashrc に以下の設定を追加すると:

~/.bashrc
shopt -s autocd

次の通り:

[user@host ~] $ /etc
cd /etc
[user@host etc]

Autojump

autojumpAUR を使うことでユーザーが頻繁に使用しているパスが記録されたデータベースを検索してファイルシステムを移動できます。

パッケージをインストールしたら /etc/profile.d/autojump.bashSource することで使えるようになります。

代替品としては zoxide があり、オリジナルの autojump と比べて機能が追加され、性能も向上しています。

ファイルの上書きを防止する

現在のセッションで、シェル出力のリダイレクトによって既存の通常ファイルが上書きされないようにするためです。

$ set -o noclobber

これは set -C と同じです。

変更をユーザーのために永続的にするためには

~/.bashrc
...
set -o noclobber

noclobber を設定した状態で、手動でファイルを上書きする場合。

$ echo "output" >| file.txt

ディレクトリスタックを使用して移動する

pushdpopd を使用すると、ディレクトリに切り替えるときにスタックにディレクトリをプッシュまたはポップできます。これは、ナビゲーション履歴を 再生 するのに役立ちます。

[user@host ~] pushd /tmp/dir1
[user@host /tmp/dir1] pushd /var/lib
[user@host/var/lib] popd
[user@host/tmp/dir1] popd
[user@host ~]

bash(1) § DIRSTACK を参照してください。

トラブルシューティング

ウィンドウをリサイズした時の行の折り返し

ターミナルエミュレータのウィンドウサイズを変更した時、Bash はリサイズシグナルを受け取れないことがあります。そうすると入力したテキストが正しく折り返されずにプロンプトをはみ出してしまいます。checkwinsize シェルオプションはコマンドごとにウィンドウサイズの確認を行い、必要ならば、LINESCOLUMNS の値を更新します。

~/.bashrc
shopt -s checkwinsize

ignoreeof が設定されているのにシェルが終了する

ignoreeof オプションを設定したのに何度も ctrl-d を押すとシェルが終了するのは、このオプションではこのキーバインド (正確には EOF 文字列) を押しても10回まではシェルが終了しないようになっているためです。

回数を上げるには、IGNOREEOF 変数を設定してください。例:

export IGNOREEOF=100

スクリプトを解析してエラーをチェックする機能

パッケージ shellcheck は bash (および他のシェル) スクリプトを解析し、考えられるエラーを表示し、よりよいコーディングを提案します。

また、このプログラムをベースにした同じ目的のウェブサイト shellcheck.net も存在します。

参照

チュートリアル

コミュニティ

サンプル