シェル入門

トップ > シェル入門

目次

シェルとは

シェルの種類

以降では、現時点で最も利用されている bash に絞って説明していきます。動作確認は bash 4.2 で行っています。他のシェルや他のバージョンでは多少異なることがあります。

プロンプト

プロンプト は「うながす」の意味で、コマンドの入力を促するために表示されます。多くの場合、ユーザ名、ホスト名、カレントディレクトリなどの情報が含まれます。末尾は一般ユーザの場合は $、スーパーユーザーの場合は # となります。

[noda@msv02 ~]$ date
Sun May 24 00:42:55 UTC 2020
[noda@msv02 ~]$

プロンプトはシェル変数 PS1 で変更できます。

[noda@msv02 ~]$ PS1='[\u@\h \W]\$ '

使用可能な特殊文字は下記の通り。

\a		# ビープ音を鳴らす
\A		# 24時間表記の時分(例:23:59)
\d		# 曜日 月 日(例:Sun May 24)
\D{fmt}		# %Y/%m/%d %H:%M:%S などのフォーマットで日時を指定
\e		# エスケープ文字(ESC)
\h		# ホスト名(例:msv02)
\H		# ホスト名(例:msv02.example.com)
\j		# バックグランドジョブの個数(例:2)
\l		# ターミナル(例:/dev/pts/2)の最後のファイル名(例:2)
\n		# 改行
\r		# キャリッジリターン
\s		# シェル名(例:bash)
\t		# 24時間表記の時刻(例:23:59:59)
\T		# 12時間表記の時刻(例:11:59:59)
\@		# AM/PM付き12時間表記の時分(例:11:59 PM)
\u		# ユーザ名(例:tanaka)
\v		# bashのバージョン(例:4.2)
\V		# bashのバージョン(例:4.2.46)
\w		# カレントディレクトリ(例:~/bin)
\W		# カレントディレクトリ(例:bin)
\!		# ヒストリ番号(例:423)
\#		# 現在のセッションにおけるヒストリ番号(例:21)
\$		# ルート権限の場合は #、一般権限の場合は $
\nnn		# 8進数nnnの文字
\\		# バックスラッシュ
\[		# 非表示シーケンスの始まり
\]		# 非表示シーケンスの終了

プロンプトの色を変更するには \e[太さ;色番号m、元に戻すには \e[m を、\[ ... \] で挟んで指定します。太さは 0 が通常、1 が太字、色は、黒(30)、赤(31)、緑(32)、黄色(33)、青(34)、マジェンダ(35)、シアン(36)、灰色(37)、白(97) などを指定できます。(→ 詳細)

[noda@msv02 ~]$ PS1='\[\e[1;32m\][\u@\h \W]\$ \[\e[m\]

`...` を用いて、コマンドの実行結果をプロンプトに表示することもできます。

[noda@msv02 ~]$ PS1='[`hostname`]\$ '

メッセージ出力(echo, printf)

echo はメッセージを標準出力に書き出します。

echo "Message..."

-n オプションをつけると改行無しで書き出します。

echo -n "Input your name: "

printf は %d や %s などのフォーマットを用いてメッセージを書き出します。

printf "name=%s/age=%d\n" "Yamada" 26

メタ文字

シェルにおいて下記の文字は特別な意味を持つ文字(メタ文字)として扱われます。

*	ファイル名マッチで0文字以上の任意文字列にマッチ
?	ファイル名マッチで1文字の任意文字にマッチ
~	ホームディレクトリ
#	コメント
\	メタ文字を無効化 (\メタ文字)
$	変数展開($FOO)
"	文字列("...$FOO..." では変数展開が行われる)
'	文字列('...$FOO...' では変数展開が行われない)
`	コマンド実行結果参照(`cmd`)
!	ヒストリ参照 (!number)
;	コマンド区切り文字(cmd1 ; cmd2)
|	コマンドのの実行結果を次のコマンドに渡す(cmd1 | cmd2)
<	リダイレクト受信(cmd < file)
>	リダイレクト送信(cmd > file)
&	コマンドをバックグランド実行(cmd &)
( )	コマンドをグループ化((cmd1; cmd2))
[ ]	if文等で使用するテストコマンド
{ }	変数展開 (${FOO})

文字列 "..." の中では \, $, " のみがメタ文字となります。文字列 '...' の中では ' のみがメタ文字となります。メタ文字を普通の文字として使用する時は、メタ文字の前に \ をつけてエスケープします。メタ文字を完全無効化したい時は文字列を '...' で囲んで、'\' にエスケープします。

echo AT\&T
echo "Character \", \$ and \\ are ..."
echo 'Character \' is ...'

シェル変数と環境変数($XXX)

bash には シェル変数環境変数 があります。シェル変数はそのシェルの中だけで使用できる変数、環境変数は子プロセスにも引き継がれる変数です。環境変数として定義された値はシェル変数としても参照できます。

set			# シェル変数を一覧表示する
FOO=xxx			# シェル変数を設定する
echo $FOO		# シェル変数を参照する
unset FOO		# シェル変数をクリアする

env			# 環境変数を一覧表示する
export BAR=xxx		# 環境変数を設定する
echo $BAR		# 環境変数を参照する
unset BAR		# 環境変数をクリアする

主な環境変数には下記などがあります。

PATH	コマンドの検索パス(例:/usr/local/sbin:/usr/local/bin...)
HOME	ホームディレクトリ(例:/home/noda)
LANG	言語情報(例:en_US.UTF-8)
PWD	カレントディレクトリ(例:/home/noda/tmp)
_	前回実行したコマンドの最後の引数

下記の様にして実行コマンドに対して、一時的な環境変数を引き渡すことができます。

[noda@msv02 ~]$ BASE_PATH=/opt/base anycommand arg1 arg2

特殊変数($x)

下記の特殊変数も使用できます。

$0	# シェルスクリプト名
$1~$9	# 1番目~9番目の引数
$*	# すべての引数(詳細後述)
$@	# すべての引数(詳細後述)
$#	# 引数の数
$?	# 直前に実行したコマンドの終了ステータス。0は成功、0以外は失敗
$-	# シェルの実行オプション (/bin/bash -opt)
$$	# シェルのプロセスID
$!	# 最後に実行したバックグランドプロセスのプロセスID
$_	# 最後に実行したコマンドの最後の引数

引数を受け取る際は、"$* "$@" "$1" の様に "..." で囲んだ方が安全です。囲まない場合、引数に * を含む文字を受け取った場合、カレントフォルダのファイル名に展開されてしまします。

command "$1"		# 安全。引数の * はそのまま参照できる
command $1		# 危険。引数の * がファイル名に展開されてしまう

$*$@ は似ていますが、"$*""$1 $2 $3 ..."と見なされるのに対し、"$@""$1" "$2" "$3" ... とみなされます。シェルスクリプトが3つの引数を受け取った場合、次のようになります。

command "$*"	# commandは"$1 $2 $3"という1つの引数を受け取る
command "$@"	# commandは"$1" "$2" "$3"という3つの引数を受け取る

変数展開(${...})

下記の例では、シェル変数 COLOR に1文字以上の値が設定されていればその値を、さもなくば white を BGCOLOR に代入します。

BGCOLOR=${COLOR:-white}

変数展開には次のようなものがあります。ここで「定義済」とは変数が定義されていること、「設定済」とは変数が定義され1文字以上の文字を設定されていることを示します。

${FOO}			# FOOの値
${FOO:-word}		# FOOが設定済であればその値、さもなくばword(FOOは未設定のまま)
${FOO:=word}		# FOOが設定済であればその値、さもなくばword(FOOにもwordを設定)
${FOO-word}		# FOOが定義済であればその値、さもなくばword(FOOは未設定のまま)
${FOO=word}		# FOOが定義済であればその値、さもなくばword(FOOにもwordを設定)
${FOO:?word}		# FOOが未設定であればwordを標準出力に出力してシェル終了
${FOO:+word}		# FOOが設定済であればword、未設定時は空文字
${FOO:n}		# FOOのn文字目(0始まり)以降の文字列
${FOO:n:m}		# FOOのn文字目(0始まり)からm文字分の文字列
${FOO#word}		# FOOの先頭からwordにマッチする部分を除外(最短マッチ)(*も使用可)
${FOO##word}		# FOOの先頭からwordにマッチする部分を除外(最大マッチ)(*も使用可)
${FOO%word}		# FOOの末尾からwordにマッチする部分を除外(最短マッチ)(*も使用可)
${FOO%%word}		# FOOの末尾からwordにマッチする部分を除外(最大マッチ)(*も使用可)
${!FOO*}		# FOOではじまる変数名の一覧
${!FOO@}		# 同上
${#FOO}			# FOOの文字数。未設定時は0
${FOO/ptn/word}	# パターンptnへのマッチ部分をwordに置換(部分マッチ,1回のみ)(*も使用可)
${FOO//ptn/word}	# パターンptnへのマッチ部分をwordに置換(部分マッチ,すべて)(*も使用可)
${FOO/#ptn/word}	# パターンptnへのマッチ部分をwordに置換(先頭マッチ)(*も使用可)
${FOO/%ptn/word}	# パターンptnへのマッチ部分をwordに置換(末尾マッチ)(*も使用可)
${FOO^}			# 最初の1文字を大文字化
${FOO^^}		# すべての文字を大文字化
${FOO,}			# 最初の1文字を小文字化
${FOO,,}		# すべての文字を小文字化
${FOO~}			# 最初の1文字を大文字・小文字反転
${FOO~~}		# すべての文字を大文字・小文字反転(何に使うんだろ...)
${FOO^[pattern]}	# patternいずれかの文字と合致時のみ大小文字変換(^^ , ~等でも可)
${!FOO[*]}		# 連想配列FOO[key]のキー一覧(連想配列はdeclare -A宣言が必要)
${!FOO[@]}		# 同上
${FOO[*]}		# 連想配列FOO[key]の値一覧(連想配列はdeclare -A宣言が必要)
${FOO[@]}		# 同上
${#FOO[*]}		# 連想配列FOO[key]の個数(連想配列はdeclare -A宣言が必要)
${#FOO[@]}		# 同上

初期化ファイル

ログイン時には次のファイルが実行されます。環境変数の設定や初期化などに使用されます。

/etc/profile		ログイン時に実行される処理(全ユーザ)
~/.bash_profile	ログイン時に一度だけ実行される処理(自分のみ)
~/.bashrc		シェル起動時に毎回実行される処理(自分のみ)

ログアウト時には次のファイルが実行されます。

/etc/bash.bash_logout	ログアウト時に実行される処理(全ユーザ)
~/.bash_logout		ログアウト時に実行される処理(自分のみ)

ファイルを変更後、再読み込みするには、一度ログアウトして再ログインするか、source コマンドまたは . コマンドでファイルを読み込みます。

[noda@msv02 ~]$ source ~/.bashrc
[noda@msv02 ~]$ . ~/.bashrc

入出力・リダイレクト(>)

コマンドは 標準入力(stdin) から読み込み、標準出力(stdout), 標準エラー出力(stderr) に書き出すことができます。

command < file			# fileの内容をcommandの標準入力に渡す

コマンドの標準出力、標準エラー出力をファイルに書き出すには次のようにします。1 は標準出力、2 は標準エラー出力、& は両方を意味します。1>> と省略できます。

command > file			# 標準出力をfileに書き出す
command 1> file		# 標準出力をfileに書き出す(>と等価)
command 2> file		# 標準エラー出力をfileに書き出す
command 1> file1 2> file2	# 標準出力をfile1に、標準エラー出力をfile2に書き出す
command &> file		# 標準出力と標準エラー出力をfileに書き出す
command >& file		# &>と同義

>>> とするとファイルを上書きするのではなく、ファイルに追記するようになります。

command >> file		# 標準出力をfileに追記する
command 1>> file		# 標準出力をfileに追記する(>>と等価)
command 2>> file		# 標準エラー出力をfileに追記する
command 1>> file1 2>> file2	# 標準出力をfile1に、標準エラー出力をfile2に追記する
command &>> file		# 標準出力と標準エラー出力をfileに追記する
command >>& file		# &>>と同義 ... と思ったら嘘。使用できない

2>&1 は 2 の出力を 1 に、1>&2 は 1 の出力を 2にマージすることを意味します。

command > file 2>&1		# &> と等価 (2を1の出力にマージする)
command >> file 2>&1		# &>> と等価 (2を1の出力にマージする)
command 1>&2			# 標準出力を標準エラー出力に書き出す

パイプ(|)

パイプ を用いて、あるコマンドの出力を、次のコマンドの標準入力に渡すことができます。パイプでは 1|, 2|, &| は使用できません。

cmd1 | cmd2			# cmd1の標準出力をcmd2の標準出力に渡す
cmd1 |& cmd2			# cmd1の標準出力と標準エラー出力をcmd2の標準出力に渡す
cmd1 2>&1 | cmd2		# &|と同義
cmd1 2> /dev/null | cmd2	# cmd1の標準エラー出力のみをcmd2に渡す

ファイルにも記録しながら画面でも確認したい時は tee コマンドが利用できます。

cmd |& tee file	# 標準出力も標準エラー出力もfileに書き込みながら画面にも表示する

バックグラウンド実行(&)

& を用いて、プロセスをバッググラウンドで実行することができます。プロセスがフォアグラウンドで起動中に Ctrl-z を押すと、プロセスは一時停止中の状態でバックグランドプロセス(ジョブ)になります。

command &		# コマンドをバックグラウンドで実行
jobs			# バックグラウンドプロセスの一覧を表示
fg %2			# 2番ののジョブをフォアグラウンドに
wait %2			# 2番のジョブの終了を待つ
kill %2			# 2番のジョブを停止
Ctrl-z			# フォアグラウンド実行中プロセスを一時停止状態に
bg %2			# 2番のジョブ(一時定期中)を再開

jobs+ 記号がついているのがカレントジョブ、- がついているのがひとつ前のジョブ。%%%+ はカレントジョブ番号、%- はひとつ前のジョブ番号、%文字列 は、コマンドラインの先頭が文字列にマッチするジョブ番号(複数マッチ時はエラー)を示します。

kill %-			# 直前に実行したジョブを停止
kill %foo		# コマンドラインがfooで始まるジョブ(1つ)を停止

ヒストリ(history)

下記のヒストリ機能を使用することができます。

history		# ヒストリの一覧を表示する
		# ひとつ前のヒストリを表示する(Ctrl-pも可)
		# ひとつ後のヒストリを表示する(Ctrl-nも可)
^str1^str1^	# 直前コマンドのstr1str2に置換
!#		# 現在入力中のコマンド
Ctrl-r		# 履歴検索モードに移行

下記のヒストリ参照を利用できます。

!!		# 直前のヒストリ
!123		# 123番目のヒストリ
!-3		# 3個前のヒストリ
!str		# strで始まる直近のヒストリ
!?str?		# strを含む直近のヒストリ(strの後ろが改行の場合は最後の?は省略可)

検索したヒストリに対して、下記の引数参照を利用できます。コマンド名は0番目の引数として扱われます。

!!:n		# n番目の引数
!!:^		# 最初の引数
!!:$		# 最後の引数
!!:n-m		# n番目からm番目までの引数
!!:^-m		# 最初からm番目までの引数
!!:n-$		# n番目から最後までの引数
!!:*		# 最初から最後までの引数(1-$)
!!:n*		# 最初から最後までの引数(n-$)
!!:n-		# 最初から最後のひとつ前までの引数
!:%		# 直近の?str?にマッチした引数

検索したヒストリや引数に対して、さらに下記を付与することができます。:で連結して複数指定できます。

:h		# ファイル名を削除
:t		# ディレクトリ名を削除
:r		# 拡張子を削除
:e		# 拡張子以外を削除
:p		# 表示はするけど実行しない
:q		# 全体を'...'で囲んで表示
:x		# 単語毎に'...'で囲んで表示
:s/str1/str2/	# str1str2に置換(最初のひとつ)
:gs/str1/str2/	# str1str2に置換(全置換)
:Gs/str1/str2/	# str1str2に置換(単語毎にひとつ)
:&		# 直前の置換を繰り返す

ディレクトリスタック(dirs)

ディレクトリを移動しまくる時、ディレクトリスタックの機能を利用すると便利です。今いるディレクトリを覚えておきたいときは pushd dir で移動し、戻る時は pupd、スタックがいくつかある時は pushd +num で移動します。numは0から数えます。スタックの0番目が常にカレントディレクトリとなります。

# スタックを表示する
dirs			# スタックの一覧を表示する(1列表示)
dirs -v			# スタックの一覧を表示する(複数行表示)
# スタックを増やす
pushd dir		# スタックの0番目にdirを追加する(先頭になるのでそこに移動する)
pushd -n dir		# スタックの1番目にdirを追加する(先頭ではないのでそこには移動しない)
# スタック全体を回転する
pushd +num		# 先頭からnum番目のスタックが先頭になるように回転し、先頭スタックに移動
pushd -num		# 末尾からnum番目のスタックが先頭になるように回転し、先頭スタックに移動
# スタックを削除する
popd			# 0番目のスタックを消す(必然的に1番目のスタックに移動する)
popd +num		# 先頭からnum番目のスタックを削除する
popd -num		# 末尾からnum番目のスタックを削除する
popd -n			# 先頭から1番目のスタックを削除する
dirs -c			# スタックをすべて削除する

条件実行(; && ||)

;, &&, || を用いて複数のコマンド実行条件を制御することができます。

cmd1 ; cmd2		# cmd1が終了したらcmd2を実行する
cmd1 && cmd2		# cmd1が成功終了したらcmd2を実行する
cmd1 || cmd2		# cmd1の終了・成功・失敗に関わらずcmd2を並行実行する

if文

if文は、条件が真の場合に処理を実行します。

if 条件; then
    処理
fi

elifelse も使用できます。下記の例では条件1が真の時は処理1を、条件2が真の時は処理2を、さもなくは処理3を実行します。

if 条件1; then
    処理1
elif 条件2; then
    処理2
else
    処理3
fi

条件の部分にはコマンドを指定します。コマンドが成功、つまり、コマンドの実行結果($?)が 0 であれば真、0 以外であれば偽とみなします。

if command1; then
    echo "成功しました"
fi

[ ... ]test コマンドの別名で、... に指定した引数を条件として判断し、合致すれば真となります。if文と組み合わせることで、条件判断ができるようになります。下記の例では、変数 TEMP が未設定または空文字であれば、/var/tmp を設定します。TEMP が未設定の場合にエラーにならないように、$TEMP を "..." で囲んでいます。

if [ "$TEMP" = "" ]; then
    TEMP=/var/tmp
fi

bash では、[ ... ] コマンドの代わりに、ビルトインの条件判断式 [[ ... ]] を使用することができます。[ ... ] よりも高速・高機能です。

if [[ "$TEMP" = "" ]]; then
    TEMP=/var/tmp
fi

[ ... ] の条件には下記などを使用できます。

( exp )			# exp をグルーピング
! exp			# exp が偽であれば
exp1 -a exp2		# exp1 かつ exp2 であれば
exp2 -o exp2		# exp1 または exp2 であれば
str1 = str2		# 文字列 str1str2 が等しければ
str1 != str2		# 文字列 str1str2 が等しくなければ>
-z str			# 文字列 str が0文字であれば(zero)
-n str			# 文字列 str が0文字で以上であれば(not zero)
str			# 文字列 str が0文字で以上であれば(-n str と同じ)
num1 -eq num2		# 数値 num1num2 と等しければ(equal)
num1 -ne num2		# 数値 num1num2 異なっていれば(not equal)
num1 -ge num2		# 数値 num1num2 以上であれば(grater than or equal)
num1 -gt num2		# 数値 num1num2 より大きければ(grater than)
num1 -le num2		# 数値 num1num2 以下であれば(less than or equal)
num1 -lt num2		# 数値 num1num2 より小さければ(less than)
file1 -ef file2	# ファイル file1file2 と同一実体であれば(equal file)
file1 -nt file2	# ファイル file1file2 より新しければ(newer than)
file1 -ot file2	# ファイル file1file2 より古ければ(older than)
-e file			# ファイル file が存在していれば
-s file			# ファイル file が0バイト以上であれば
-f file			# ファイル file がレギュラーファイルであれば
-r file			# ファイル file が読み込み可能であれば
-w file			# ファイル file が書き込み可能であれば
-x file			# ファイル file が実行可能(ディレクトリの場合は移動可能)であれば
-d file			# ファイル file がディレクトリであれば
-h file			# ファイル file がシンボリックリンクファイルであれば(-Lと同義)
-L file			# ファイル file がシンボリックリンクファイルであれば(-hと同義)
-b file			# ファイル file がブロックデバイスファイルであれば
-c file			# ファイル file がキャラクタデバイスファイルであれば
-p file			# ファイル file が名前付きパイプであれば
-S file			# ファイル file がソケットファイルであれば
-k file			# ファイル file にスティッキービットが設定されていれば(chown o+t)
-u file			# ファイル file にセットユーザIDビットが設定されていれば(chown u+s)
-g file			# ファイル file にセットグループIDビットが設定されていれば(chown g+s)
-O file			# ファイル file が実効ユーザIDに所有されていれば
-G file			# ファイル file が実効グループIDに所有されていれば
-t fd			# ファイルディスクリプタ fd がターミナルとして開かれていれば

[[ ... ]] の条件には追加で下記などを使用できます。

exp1 && exp2		# exp1 かつ exp2 であれば
exp2 || exp2		# exp1 または exp2 であれば

for文

for ... in 文は、リストをひとつずつ変数に格納しながらループします。下記の例では引数 $@ を順番にひとつずつ処理していきます。引数の * や ? がファイル名に展開されないように "..." で囲んでいます。

for i in "$@"
do
    echo "$i"
done

{n..m} は、nmまでの数値のリストを返却します。下記の例は 1~10 のループを回します。詳細は ブレース展開 を参照してください。

for i in {1..10}
do
    echo "$i"
done

bash では下記の様な記述もできます。

for ((i = 0; i <= 10; i++)) {
    echo "$i"
}

while文

while文は、条件が真の間処理をループします。次の例は標準入力から入力が無くなるまで read コマンドで1行ずつ読み込み、処理します。

while read line
do
    echo $line
done

until文

until文は、条件が真になるまで処理をループします。下記の例は、0~9 のループを回します。

i=1
until [ $i -eq 10 ]
do
    echo $i
    i=`expr $i + 1`
done

case文

case文は、文字列のパターンによって処理を振り分けます。パターンには *? のワイルドカードも使用できます。

case $FILENAME in
  *.txt)  echo "Text file." ;;
  *.html) echo "HTML file." ;;
  *)      echo "Unknwown file." ;;
esac

select文

select文は、選択肢を表示し、入力を受け取るループを回します。下記の例は色を選択してもらう例です。ループを抜けるには break します。

select i in Red Green Blue
do
    case $i in
      Red)   echo "Red!!"; break ;;
      Green) echo "Green!!"; break ;;
      Blue)  echo "Blue!!"; break ;;
      *)     echo "Bad select!!" ;;
    esac
done

実行すると下記の様に表示し、選択を促します。

1) Red
2) Green
3) Blue
#?    ← 1 か 2 か 3 を入力して Enter

エイリアス(alias)

インタラクティブモードのシェルではエイリアスを使用することができます。

alias			# 定義済みエイリアス一覧を表示する
alias ll='ls -l'	# エイリアスを定義する
unalias ll		# エイリアスを削除する

関数(function)

下記の様に関数を定義することができます。

function myfunc() {
    echo "func is called."
}

function は省略可能です。

myfunc() {
    echo "func is called."
}

関数はコマンドの様に呼び出すことができます。

myfunc arg1 arg2 arg3

引数は、$0, $1, $2, ... $*, $@, $# で参照します。

myfunc() {
    for i in "$@"
    do
        echo "[$i]"
    done
}

ブレース展開({...})

比較的新しくサポートされた機能ですが、ブレース {...} で囲まれた文字を展開できる機能があります。for文 と組み合わせることにより威力を発揮します。

{1..10}			# 1 2 3 ...10 に展開
{1..10..2}		# 2個とばしに 1 3 5 7 9 に展開
{aa,bb,cc}		# aa bb cc に展開
file.{txt,bak}		# file.txt file.back に展開
file{1..3}.txt		# file1.txt file2.txt file3.txt に展開
file{1..3}.{txt,bak}	# file1.txt file1.bak file2.txt ... に展開

シェルオプション(set)

bask の引数もしくは set コマンドで、シェル自体の動作に関するオプションを指定することができます。

/bin/bash -opt			# シェル起動時のオプションで指定
set -o				# シェルオプションの一覧を表示する
set -opt			# setコマンドで有効にする(例:set -a)
set -o option			# setコマンドで有効にする(例:set -o allexport)
set +opt			# setコマンドで無効にする(例:set +a)
set +o option			# setコマンドで無効にする(例:set +o allexport)

例えばシェルスクリプトの中で下記の様にオプションを設定すると、コマンドの実行トレースを表示するようになります。

#!/bin/bash -x
command...

下記の様に set を用いると、オプションを設定した箇所以降でトレースが有効になります。

#!/bin/bash
command...
set -x		# set -o xtrace と同意
command...

指定可能なオプションには下記があります。

# 展開系
allexport(-a)			# シェル変数が設定されたら環境変数に自動的にexportする
braceexpand(-B)		# ブレース展開を有効にする
noglob(-f)			# *や?のファイル名展開を無効にする

# ヒストリ系
history				# ヒストリ機能を有効にする
histexpand(-H)			# !番号によるヒストリの参照を有効にする

# 操作モード系
emacs				# コマンド編集キーをEmacs風にする
vi				# コマンド編集キーをvi風にする
posix				# POSIX互換モードで動作する

# デバッグ系
errexit(-e)			# コマンドがひとつでもエラーになればシェルを終了する
pipefail			# パイプライン中のコマンドがひとつでもエラーになればパイプを終了する
errtrace(-E)			# エラートラップ(trace '...' ERR)を有効にする
functrace(-T)			# 関数の中でもトラップを発生させる
xtrace(-x)			# コマンド実行トレース表示機能を有効にする
verbose(-v)			# シェル実行トレース表示機能を有効にする
noexec(-n)			# 文法チェックのみ行い実行しない

# 安全性
noclobber(-C)			# リダイレクトによるファイルの上書きを禁止する
ignoreeof			# Ctrl-D でログアウトしない
nounset(-u)			# 未定義の変数参照をエラーとする($*,$@は除く)
physical(-P)			# cdコマンド等でシンボリックリンクをたどらない
privileged(-p)			# 特権モード。各種変数や実行ユーザIDを周りから受け取らない
interactive-comments		# コメント(#)を利用可能にする(インタラクティブモードのみ)

# 通知系
monitor(-m)			# バックグラウンドプロセスの終了を通知する
notify(-b)			# バックグラウンドプロセス終了時即座に通知する

# その他
hashall(-h)			# ディレクトリハッシュテーブルをすべて記録する
keyword(-k)			# コマンド引数に指定した代入文も環境変数としてコマンドに渡す
onecmd(-t)			# コマンドをひとつ読み込み、実行してから終了する(詳細不明)
nolog				# 未使用

Copyright (C) 2020 杜甫々
初版:2020年5月24日 最終更新:2020年6月16日
http://www.tohoho-web.com/ex/shell.html