Last Update 2023/02/27
シェル組み込みコマンド
-A alias
-A arrayvar
-A binding
-A builtin
-A command
-A directory
-A disabled
-A enabled
-A export
-A file
-A function
-A group
-A helptopic
-A job
-A keyword
-A running
-A setopt
-A shopt
-A signal
-A stopped
-A user
-A variable
-C オプション
-F オプション
-G オプション
-S オプション
-W オプション
-X オプション
-o default
-o dirnames
-o filenames
-o nosort
-o plusdirs
-A arrayvar
-A binding
-A builtin
-A command
-A directory
-A disabled
-A enabled
-A export
-A file
-A function
-A group
-A helptopic
-A job
-A keyword
-A running
-A setopt
-A shopt
-A signal
-A stopped
-A user
-A variable
-C オプション
-F オプション
-G オプション
-S オプション
-W オプション
-X オプション
-o default
-o dirnames
-o filenames
-o nosort
-o plusdirs
-p オプション
-f オプション
-F オプション
-g オプション
-I オプション
-a オプション
-A オプション
-i オプション
-l オプション
-n オプション
-r オプション
-u オプション
-x オプション
+ (属性の削除)
-f オプション
-F オプション
-g オプション
-I オプション
-a オプション
-A オプション
-i オプション
-l オプション
-n オプション
-r オプション
-u オプション
-x オプション
+ (属性の削除)
(15) dirs
(16) echo
(17) enable
(18) eval
(19) exec
(20) exit
(21) export
(22) fc
(23) fg (ジョブコントロールのページ)
(24) getopts
(25) hash
(26) help
(27) history
(28) jobs
(29) kill
(30) let
(31) local
(32) logout
(33) mapfile
(34) popd
(35) printf
(36) pushd
(37) pwd
(38) read
オプション無し
-a オプション
-d オプション
-e オプション
-i オプション
-n オプション
-N オプション
-p オプション
-r オプション
-s オプション
-t オプション
-u オプション
-a オプション
-d オプション
-e オプション
-i オプション
-n オプション
-N オプション
-p オプション
-r オプション
-s オプション
-t オプション
-u オプション
(39) readonly
(40) return
(41) set
オプション無し
-a オプション
-b オプション
-e オプション
-f オプション
-h オプション
-k オプション
-n オプション
-u オプション
-v オプション
-x オプション
-B オプション
-C オプション
-H オプション
-P オプション
-- オプション
「-」
-o オプション
-a オプション
-b オプション
-e オプション
-f オプション
-h オプション
-k オプション
-n オプション
-u オプション
-v オプション
-x オプション
-B オプション
-C オプション
-H オプション
-P オプション
-- オプション
「-」
-o オプション
(42) shift
(43) shopt
(44) test
(45) times
(46) type
(47) ulimit
(48) umask
(49) unalias
(50) unset
(01)
現在のシェル環境で、[ファイル名]からコマンドを読み取って実行
sample1.sh
#!/bin/bash
echo "sample1"
実行結果
$ . sample1.sh
sample1 <--- ファイルを読み込んで実行
$ source sample1.sh
sample1 <--- 〃
(02)
引数無しまたは-pオプション : エイリアスリストを出力
引数あり : [値]が与えられた[名前]に対してエイリアスを設定
引数あり : [値]が与えられた[名前]に対してエイリアスを設定
sample1.sh
#!/bin/bash
echo "sample1"
実行結果
$ alias spl='source sample1.sh' <--- テスト用エイリアス「spl」を設定
$ spl <--- エイリアスを入力
sample1
$ alias -p <--- エイリアスのリストを出力
alias spl='source sample1.sh'
(03)
中断されたジョブをバックグラウンドで再開
sample1.sh
#!/bin/bash
declare -a ary=(a b c)
for a in ${ary[@]}
do
date
echo "--- $a ---"
sleep 3
done
date
実行結果
$ ./sample1.sh
Sat 8 Oct 11:33:10 JST 2022
--- a ---
^Z <--- ジョブ実行中に[C-z]で停止
[1]+ Stopped ./sample1.sh
$ bg %1 <--- バックグラウンドで再開
[1]+ ./sample1.sh &
$ Sat 8 Oct 11:33:25 JST 2022
--- b ---
Sat 8 Oct 11:33:28 JST 2022
--- c ---
Sat 8 Oct 11:33:31 JST 2022
[1]+ Done ./sample1.sh <--- 終了表示
$
(04)
readlineのキー、関数、変数に関する設定・表示
$ bind -l
abort <--- readline関数リスト
accept-line
alias-expand-line
︙
yank-last-arg
yank-nth-arg
yank-pop
$ bind -p
"\C-g": abort <--- readline関数名とキーへの割り当て一覧(再読込可能な形式)
"\C-x\C-g": abort
"\e\C-g": abort
︙
"\e_": yank-last-arg
"\e\C-y": yank-nth-arg
"\ey": yank-pop
$ bind -P
abort can be found on "\C-g", "\C-x\C-g", "\e\C-g". <--- 現在のreadline関数名とキーへの割り当て一覧
accept-line can be found on "\C-j", "\C-m".
alias-expand-line is not bound to any keys
︙
yank-last-arg can be found on "\e.", "\e_".
yank-nth-arg can be found on "\e\C-y".
yank-pop can be found on "\ey".
$ bind -v
set bind-tty-special-chars on <--- readlineの変数名と値の一覧(再読込可能な形式)
set blink-matching-paren off
set byte-oriented off
︙
set keyseq-timeout 500
set vi-cmd-mode-string (cmd)
set vi-ins-mode-string (ins)
$ bind -V
bind-tty-special-chars is set to `on' <--- 現在のreadlineの変数名と値の一覧
blink-matching-paren is set to `off'
byte-oriented is set to `off'
︙
keyseq-timeout is set to `500'
vi-cmd-mode-string is set to `(cmd)'
vi-ins-mode-string is set to `(ins)'
サンプルファイル(sample_inputrc)
"\ey": yank-last-arg
実行前
$ bind -q yank-last-arg <--- -qオプションで関数yank-last-argが割り当てられているキーの問い合わせ
yank-last-arg can be invoked via "\e.", "\e_".
$ bind -q yank-pop <--- -qオプションで関数yank-popが割り当てられているキーの問い合わせ
yank-pop can be invoked via "\ey". <--- "\ey"にyank-popが割り当てられている
実行結果
$ bind -f sample_inputrc <--- ファイル「sample_inputrc」からキーバインディングを読み込み
$ bind -q yank-last-arg
yank-last-arg can be invoked via "\e.", "\e_", "\ey". <--- "\ey"に割り当てられた関数がyank-last-argに変更
$ bind -q yank-pop
yank-pop is not bound to any keys. <--- yank-popが割り当てられたキーは無し
$ bind -P
abort can be found on "\C-g", "\C-x\C-g", "\e\C-g". <--- abortに割り当てられているキー
accept-line can be found on "\C-j", "\C-m".
︙
$ bind -u abort <--- abortに割り当てられている全てのキーを解除
$ bind -P
abort is not bound to any keys <--- 割り当てられている全てのキーが解除されている
accept-line can be found on "\C-j", "\C-m".
︙
$ bind -P
abort can be found on "\C-g", "\C-x\C-g", "\e\C-g". <--- abortに割り当てられているキー
accept-line can be found on "\C-j", "\C-m".
︙
$ bind -r "\C-g" <--- キー"\C-g"への割り当てを削除
$ bind -P
abort can be found on "\C-x\C-g", "\e\C-g". <--- abortに割り当てられているキーのリストから"\C-g"キーが削除される
accept-line can be found on "\C-j", "\C-m".
(05)
for、while、until、selectループの中から抜ける
サンプルファイル(sample.sh)
#!/bin/bash
# ループに使用する配列
declare -a ary1=(a b c d)
declare -a ary2=(1 2 3)
for a in ${ary1[@]}
do
# 1段目ループ
echo "$a"
for b in ${ary2[@]}
do
# 2段目ループ
echo "--- $b"
if [[ $a == "b" ]] && [[ $b == "1" ]]; then
echo "1段目ループへ"
break
elif [[ $a == "c" ]] && [[ $b == "2" ]]; then
echo "全ループ終了"
break 2
fi
done
done
実行結果
$ ./sample.sh
a
--- 1
--- 2
--- 3
b
--- 1
1段目ループへ <--- 「break」で2段目ループを抜ける
c
--- 1
--- 2
全ループ終了 <--- 「break 2」で2段階分ループを抜ける
(06)
指定されたシェル組み込みコマンドに引数を渡して実行
サンプルファイル(sample.sh)
#!/bin/bash
# 関数名を組み込みコマンドと同じ名前で宣言
function echo
{
# 「builtin」を使用し、関数内で組み込みコマンド「echo」呼び出し
builtin echo "function echo"
}
# 「builtin」使用せずにシェルスクリプト関数「echo」呼び出し
echo
# 「builtin」を使用し、組み込みコマンド「echo」呼び出し
builtin echo "builtin echo"
実行結果
$ ./sample.sh
function echo <--- シェルスクリプト関数「echo」内からの組み込みコマンド「echo」の呼び出し
builtin echo <--- 組み込みコマンド「echo」の呼び出し
(07)
アクティブなサブルーチン呼び出し(シェル関数、「.」や「source」組み込みコマンドで実行されるスクリプト)の関連情報を表示
サンプルファイル(sample.sh)
$ cat sample.sh
#!/bin/bash
function samplefunc1
{
echo "samplefunc1の実行"
list_caller
echo
samplefunc2
}
function samplefunc2
{
echo "samplefunc2の実行"
list_caller
echo
samplefunc3
}
function samplefunc3
{
echo "samplefunc3の実行"
list_caller
echo
}
function list_caller
{
echo "現在のFUNCNAME配列数 : ${#FUNCNAME[@]}"
for (( i=0 ; i < ${#FUNCNAME[@]} ; i++ ))
do
caller $i
done
echo "callerのみ"
caller
}
samplefunc1
echo "関数実行終了"
echo "現在のFUNCNAME配列数 : ${#FUNCNAME[@]}"
for (( i=0 ; i < ${#FUNCNAME[@]} ; i++ ))
do
caller $i
done
実行結果
$ ./sample.sh
samplefunc1の実行
現在のFUNCNAME配列数 : 3
6 samplefunc1 ./sample.sh <--- 引数付きcallerによる出力(呼び出し行番号、サブルーチン名、ソースファイル)
38 main ./sample.sh
callerのみ
6 ./sample.sh <--- 引数無しcallerによる出力(呼び出し行番号、ソースファイル)
samplefunc2の実行
現在のFUNCNAME配列数 : 4
14 samplefunc2 ./sample.sh
8 samplefunc1 ./sample.sh
38 main ./sample.sh
callerのみ
14 ./sample.sh
samplefunc3の実行
現在のFUNCNAME配列数 : 5
22 samplefunc3 ./sample.sh
16 samplefunc2 ./sample.sh
8 samplefunc1 ./sample.sh
38 main ./sample.sh
callerのみ
22 ./sample.sh
関数実行終了
現在のFUNCNAME配列数 : 0
(08)
カレントディレクトリを変更
実行結果(1)
引数にディレクトリ名を指定して実行
引数にディレクトリ名を指定して実行
$ cd / <--- カレントディレクトリを「/」ディレクトリに変更
$ pwd
/ <--- 変更を確認
実行結果(2)
引数無しで実行
引数無しで実行
$ echo $HOME
/home/testusr <--- 現在の変数「HOME」の値
$ cd <--- ディレクトリ名指定無しで実行
$ pwd
/home/testusr <--- ディレクトリ名指定無しの場合は、変数「HOME」の値へ移動
実行結果(3)
ディレクトリにシンボリックリンクを指定
ディレクトリにシンボリックリンクを指定
$ ls -l symdir0
lrwxrwxrwx 1 testusr testusr 8 Oct 14 11:28 symdir0 -> workdir0 <--- 「symdir0」は「workdir0」へのシンボリックリンク
$ cd symdir0 <--- オプション無しでシンボリックリンクを指定
$ pwd
/home/testusr/symdir0 <--- 移動先はシンボリックリンク
$ cd ..
$ cd -P symdir0 <--- -Pオプション付きでシンボリックリンクを指定
$ pwd
/home/testusr/workdir0 <--- 移動先はリンク先ディレクトリ
(09)
通常のシェル関数を検索せず、組み込みコマンドとPATHにあるコマンドを実行
サンプルファイル(sample.sh)
#!/bin/bash
# PATHにあるコマンドと同名のシェル関数
function ls
{
echo "function ls"
}
# 組み込みコマンド「command」を使用せずに「ls」を実行
ls
# 組み込みコマンド「command」の引数として「ls」を実行
command ls
実行結果
$ ./sample.sh
function ls <--- 「command」を使用しない場合はシェル関数を呼び出す
sample1.txt sample2.txt sample3.txt sample.sh workdir0 workdir1 workdir2 <--- 「command」でPATHにあるコマンドを実行
(10)
complete組み込みコマンドが受け付けるオプションに従って、マッチする補完候補のリストを出力
実行結果
$ ls -al
total 68
drwxr-xr-x 5 testusr testusr 4096 Oct 13 15:53 .
drwxr-xr-x 4 root root 4096 Sep 7 20:53 ..
-rw------- 1 testusr testusr 9229 Oct 13 16:14 .bash_history
-rw-rw-r-- 1 testusr testusr 35 Oct 10 15:19 .inputrc
-rw-rw-r-- 1 testusr testusr 4 Sep 20 16:59 sample1.txt
-rw-rw-r-- 1 testusr testusr 4 Sep 20 16:59 sample2.txt
-rw-rw-r-- 1 testusr testusr 4 Sep 20 16:59 sample3.txt
-rwxr-xr-x 1 testusr testusr 611 Oct 13 15:53 sample.sh
-rw------- 1 testusr testusr 10683 Oct 13 15:53 .viminfo
-rw------- 1 testusr testusr 0 Oct 12 12:20 .viminfo.tmp
-rw------- 1 testusr testusr 0 Oct 12 12:20 .viminfz.tmp
-rw-rw-r-- 1 testusr testusr 138 Oct 12 17:47 .vimrc
drwxrwxr-x 2 testusr testusr 4096 Sep 30 16:26 workdir0
drwxrwxr-x 2 testusr testusr 4096 Sep 30 16:26 workdir1
drwxrwxr-x 2 testusr testusr 4096 Sep 30 16:27 workdir2
$ compgen -f <--- -fオプションでファイル名を補完候補対象として指定
workdir2
.viminfo.tmp
sample.sh
workdir1
.viminfo
.bash_history
sample1.txt
.vimrc
.inputrc
sample3.txt
.viminfz.tmp
workdir0
sample2.txt
$ compgen -f . <--- 「.」で始まるファイル名を補完候補対象として指定
.viminfo.tmp
.
.viminfo
.bash_history
.vimrc
.inputrc
..
.viminfz.tmp
(11)
引数に指定された「名前」をどのように補完されるかを指定
$ alias aa='echo aa' <--- テスト用エイリアスを定義
$ alias bb='echo bb' <--- 〃
$ alias cc='echo cc' <--- 〃
$ complete -A alias fg <--- コマンド「fg」の補完の生成をエイリアス名に指定
$ fg [TAB] <--- 「complete」実行後のコマンド「fg」に対する補完を確認
aa bb cc <--- エイリアス名から成る補完候補リスト
$ declare -a aa=(1 2 3) <--- テスト用配列変数を定義
$ declare -a bb=(4 5 6) <--- 〃
$ declare -a cc=(7 8 9) <--- 〃
$ complete -A arrayvar echo <--- コマンド「echo」の補完の生成を配列変数名に指定
$ echo [TAB] <--- 「complete」実行後のコマンド「echo」に対する補完を確認
aa BASH_ARGC BASH_CMDS BASH_SOURCE bb DIRSTACK PIPESTATUS <--- 配列変数名から成る補完候補リスト
BASH_ALIASES BASH_ARGV BASH_LINENO BASH_VERSINFO cc GROUPS
$ complete -A binding echo <--- コマンド「echo」の補完の生成をReadlineキー割り当て名に指定
$ echo [TAB] <--- 「complete」実行後のコマンド「echo」に対する補完を確認
Display all 169 possibilities? (y or n)
abort history-search-backward upcase-word <--- Readlineキー割り当て名から成る補完候補リスト
accept-line history-search-forward vi-append-eol
alias-expand-line history-substring-search-backward vi-append-mode
︙
glob-list-expansions unix-filename-rubout yank-pop
history-and-alias-expand-line unix-line-discard
history-expand-line unix-word-rubout
$ complete -A builtin fg <--- コマンド「fg」の補完の生成をシェル組み込みコマンド名に指定
$ fg [TAB] <--- 「complete」実行後のコマンド「fg」に対する補完を確認
. break complete echo false history mapfile readarray source type wait <--- シェル組み込みコマンド名から成る補完候補リスト
: builtin compopt enable fc jobs popd readonly suspend typeset
[ caller continue eval fg kill printf return test ulimit
alias cd declare exec getopts let pushd set times umask
bg command dirs exit hash local pwd shift trap unalias
bind compgen disown export help logout read shopt true unset
$ complete -A command fg <--- コマンド「fg」の補完の生成をコマンド名に指定
$ fg [TAB] <--- 「complete」実行後のコマンド「fg」に対する補完を確認
Display all 783 possibilities? (y or n)
! grub-mkimage psfxtable <--- コマンド名から成る補完候補リスト
./ grub-mklayout psktool
: grub-mknetdir pslog
︙
grub-glue-efi psfaddtable zless
grub-kbdcomp psfgettable zmore
grub-menulst2cfg psfstriptable znew
$ ls -l <--- カレントディレクトリ内の現状を確認
total 28
drwxrwxr-x 2 testusr testusr 4096 Oct 19 22:59 aaa
drwxrwxr-x 2 testusr testusr 4096 Oct 19 22:59 bbb
drwxrwxr-x 2 testusr testusr 4096 Oct 19 22:59 ccc
-rw-rw-r-- 1 testusr testusr 4 Sep 20 16:59 sample1.txt
-rw-rw-r-- 1 testusr testusr 4 Sep 20 16:59 sample2.txt
-rw-rw-r-- 1 testusr testusr 4 Sep 20 16:59 sample3.txt
-rwxr-xr-x 1 testusr testusr 611 Oct 13 15:53 sample.sh
$ complete -A directory ls <--- コマンド「fg」の補完の生成をディレクトリ名に指定
$ ls [TAB] <--- 「complete」実行後のコマンド「ls」に対する補完を確認
aaa/ bbb/ ccc/ <--- ディレクトリ名から成る補完候補リスト
$ enable -n eval trap umask <--- テスト用として「eval」「trap」「umask」を無効化
$ complete -A disabled fg <--- コマンド「fg」の補完の生成を無効なシェル組み込みコマンド名に指定
$ fg [TAB] <--- 「complete」実行後のコマンド「fg」に対する補完を確認
eval trap umask <--- 無効なシェル組み込みコマンド名から成る補完候補リスト
無効化したコマンドは「enable eval trap umask」で再有効化
$ complete -A enabled fg <--- コマンド「fg」の補完の生成を有効なシェル組み込みコマンド名に指定
$ fg [TAB] <--- 「complete」実行後のコマンド「fg」に対する補完を確認
. break complete echo false history mapfile readarray source type wait <--- 有効なシェル組み込みコマンド名から成る補完候補リスト
: builtin compopt enable fc jobs popd readonly suspend typeset
[ caller continue eval fg kill printf return test ulimit
alias cd declare exec getopts let pushd set times umask
bg command dirs exit hash local pwd shift trap unalias
bind compgen disown export help logout read shopt true unset
$ complete -A export unset <--- コマンド「unset」の補完の生成をエクスポートされたシェル変数名に指定
$ unset [TAB] <--- 「complete」実行後のコマンド「unset」に対する補完を確認
HOME MAIL PATH SHELL SSH_CLIENT SSH_TTY USER <--- エクスポートされたシェル変数名から成る補完候補リスト
LOGNAME OLDPWD PWD SHLVL SSH_CONNECTION TERM
$ complete -A directory ls <--- 比較用としてコマンド「ls」の補完リストの生成対象をディレクトリ名に設定
$ ls [TAB] <--- 「complete」実行後のコマンド「ls」に対する補完を確認
aaa/ bbb/ ccc/ <--- ディレクトリ名から成る補完候補リスト(比較用)
$ complete -r <--- 補完リストの生成設定を削除
$ complete -A file ls <--- コマンド「ls」の補完リストの生成対象をファイル名に設定
$ ls [TAB] <--- 「complete」実行後のコマンド「ls」に対する補完を確認
aaa/ bbb/ .inputrc sample2.txt sample.sh .viminfo.tmp .vimrc <--- ファイル名から成る補完候補リスト
.bash_history ccc/ sample1.txt sample3.txt .viminfo .viminfz.tmp
$ function aa_samplefunc { echo aa; } <--- テスト用関数の作成
$ function bb_samplefunc { echo bb; } <--- 〃
$ function cc_samplefunc { echo cc; } <--- 〃
$ complete -A function echo <--- コマンド「echo」の補完の生成をシェル関数名に指定
$ echo [TAB] <--- 「complete」実行後のコマンド「echo」に対する補完を確認
aa_samplefunc bb_samplefunc cc_samplefunc <--- シェル関数名から成る補完候補リスト
$ complete -A group echo <--- コマンド「echo」の補完の生成をグループ名に指定
$ echo [TAB] <--- 「complete」実行後のコマンド「echo」に対する補完を確認
adm disk nogroup systemd-journal-remote tty <--- グループ名から成る補完候補リスト
apache floppy root systemd-journal-upload usb
audio input sshd systemd-network users
︙
$ complete -A helptopic help <--- コマンド「help」の補完の生成を組み込みコマンド「help」が受け付けるトピック名に指定
$ help "[TAB] <--- 「complete」実行後のコマンド「help」に対する補完を確認
% bg command dirs export getopts let pwd shift trap unset <--- 組み込みコマンド「help」が受け付けるトピック名から成る補完候補リスト
(( ... )) bind compgen disown false hash local read shopt true until
. break complete echo fc help logout readarray source type variables
︙
サンプルファイル(aa.sh、bb.sh、cc.sh)
#!/bin/bash
sleep 300
実行結果
([TAB]はタブキー(計3回)押し下げカーソル位置。2回目以降は「./」が付加)
([TAB]はタブキー(計3回)押し下げカーソル位置。2回目以降は「./」が付加)
$ ./aa.sh & <--- テスト用ジョブをバックグラウンドで実行
[1] 283
$ ./bb.sh & <--- 〃
[2] 285
$ ./cc.sh & <--- 〃
[3] 287
$ complete -A job echo <--- コマンド「echo」の補完の生成をジョブ名に指定
$ echo [TAB] <--- 「complete」実行後のコマンド「echo」に対する補完を確認
./aa.sh ./bb.sh ./cc.sh <--- ジョブ名から成る補完候補リスト
$ complete -A keyword echo <--- コマンド「echo」の補完の生成をシェルの予約語に指定
$ echo
! ]] } coproc done else fi function in then until <--- シェルの予約語から成る補完候補リスト
[[ { case do elif esac for if select time while
サンプルファイル(aa.sh、bb.sh、cc.sh)
#!/bin/bash
sleep 300
実行結果
([TAB]はタブキー(計3回)押し下げカーソル位置。2回目以降は「./」が付加)
([TAB]はタブキー(計3回)押し下げカーソル位置。2回目以降は「./」が付加)
$ complete -A running echo <--- コマンド「echo」の補完の生成を実行中のジョブ名に指定
$ ./aa.sh & <--- テスト用ジョブをバックグラウンドで実行
[1] 280
$ ./bb.sh <--- テスト用ジョブを実行
^Z
[2]+ Stopped ./bb.sh <--- テスト用ジョブを停止
$ ./cc.sh & <--- テスト用ジョブをバックグラウンドで実行
[3] 284
$ echo [TAB] <--- 「complete」実行後のコマンド「echo」に対する補完を確認
./aa.sh ./cc.sh <--- 実行中のジョブ名から成る補完候補リスト
$ complete -A setopt set <--- コマンド「set」の補完の生成をset組み込みコマンドの-oオプションの引数に指定
$ set -o [TAB] <--- 「complete」実行後のコマンド「set」に対する補完を確認
allexport functrace interactive-comments noglob physical vi <--- set組み込みコマンドの-oオプションの引数から成る補完候補リスト
braceexpand hashall keyword nolog pipefail xtrace
emacs histexpand monitor notify posix
errexit history noclobber nounset privileged
errtrace ignoreeof noexec onecmd verbose
$ complete -A shopt shopt <--- コマンド「shopt」の補完の生成をshopt組み込みコマンドが受け付けるシェルオプション名に指定
$ shopt [TAB] <--- 「complete」実行後のコマンド「shopt」に対する補完を確認
assoc_expand_once compat41 extglob huponexit no_empty_cmd_completion <--- shopt組み込みコマンドが受け付けるシェルオプション名から成る補完候補リスト
autocd compat42 extquote inherit_errexit nullglob
cdable_vars compat43 failglob interactive_comments progcomp
︙
$ complete -A signal kill <--- コマンド「shopt」の補完の生成をシグナル名に指定
$ kill [TAB] <--- 「complete」実行後のコマンド「kill」に対する補完を確認
DEBUG SIGCHLD SIGJUNK(32) SIGRTMAX SIGRTMAX-2 SIGRTMAX-9 SIGRTMIN+14 SIGRTMIN+7 SIGTERM SIGUSR2 <--- シグナル名から成る補完候補リスト
ERR SIGCONT SIGJUNK(33) SIGRTMAX-1 SIGRTMAX-3 SIGRTMIN SIGRTMIN+15 SIGRTMIN+8 SIGTRAP SIGVTALRM
EXIT SIGFPE SIGKILL SIGRTMAX-10 SIGRTMAX-4 SIGRTMIN+1 SIGRTMIN+2 SIGRTMIN+9 SIGTSTP SIGWINCH
︙
サンプルファイル(aa.sh、bb.sh、cc.sh)
#!/bin/bash
sleep 300
実行結果
([TAB]はタブキー(計3回)押し下げカーソル位置。2回目以降は「./」が付加)
([TAB]はタブキー(計3回)押し下げカーソル位置。2回目以降は「./」が付加)
$ complete -A stopped echo <--- コマンド「echo」の補完の生成を停止中のジョブ名に指定
$ ./aa.sh <--- テスト用ジョブを実行
^Z
[1]+ Stopped ./aa.sh <--- テスト用ジョブを停止
$ ./bb.sh & <--- テスト用ジョブをバックグラウンドで実行
[2] 276
$ ./cc.sh <--- テスト用ジョブを実行
^Z
[3]+ Stopped ./cc.sh <--- テスト用ジョブを停止
$ echo ./ [TAB] <--- 「complete」実行後のコマンド「echo」に対する補完を確認
./aa.sh ./cc.sh <--- 停止中のジョブ名から成る補完候補リスト
$ complete -A user echo <--- コマンド「echo」の補完の生成をユーザー名に指定
$ echo [TAB] <--- 「complete」実行後のコマンド「echo」に対する補完を確認
apache messagebus systemd-bus-proxy systemd-journal-upload testusr <--- ユーザー名から成る補完候補リスト
bin nobody systemd-coredump systemd-network
︙
$ complete -A variable echo <--- コマンド「echo」の補完の生成を全てのシェル変数名に指定
$ echo [TAB] <--- 「complete」実行後のコマンド「echo」に対する補完を確認
_ BASHOPTS EPOCHREALTIME HOME LOGNAME OSTYPE RANDOM TERM <--- 全てのシェル変数名から成る補完候補リスト
BASH BASHPID EPOCHSECONDS HOSTNAME LS_COLORS PATH SECONDS UID
BASH_ALIASES BASH_SOURCE EUID HOSTTYPE MACHTYPE PIPESTATUS SHELL USER
︙
サンプルファイル(sample.sh)
#!/bin/bash
declare -a sample1=("aa" "bb" "cc")
n=0
for a in "${sample1[@]}"
do
echo "$a($n)"
(( n+=1 ))
done
実行結果
([TAB]はタブキー(2回)押し下げカーソル位置)
([TAB]はタブキー(2回)押し下げカーソル位置)
$ complete -C ./sample.sh echo <--- 「sample.sh」の実行結果を使用して補完項目を生成
$ echo [TAB] <--- 「complete」実行後のコマンド「echo」に対する補完を確認
aa(0) bb(1) cc(2) <--- 「sample.sh」の実行結果から成る補完候補リスト
$ function aa_samplefunc { COMPREPLY=("aa($1)" "bb($2)" "cc($3)"); } <--- テスト用の関数を定義
$ complete -F aa_samplefunc echo <--- 関数「aa_samplefunc」の実行結果を使用して補完項目を生成
$ echo -e a <--- 「complete」実行後のコマンド「echo」に対する補完を確認
aa(echo) bb(a) cc(-e) <--- 関数「aa_samplefunc」で生成されるCOMPREPLYの値から生成される補完候補リスト
関数に渡される引数
$1 : 引数が補完されるコマンド名
$2 : 補完される単語
$2 : 現在のコマンドライン上で補完される単語の前の単語
$ complete -G '*.txt' echo <--- コマンド「echo」の補完の生成を「*.txt」のパス名展開の結果に指定
$ echo [TAB] <--- 「complete」実行後のコマンド「echo」に対する補完を確認
sample1.txt sample2.txt sample3.txt <--- 「*.txt」のパス名展開の結果から成る補完候補リスト
$ complete -f -S '.txt' echo <--- 「echo」コマンドの補完の生成をファイル名に指定し、すべての候補に接尾辞として「.txt」を付加
$ echo [TAB] <--- 「complete」実行後のコマンド「echo」に対する補完を確認
.bash_history.txt sample1.txt.txt sample3.txt.txt .viminfo.txt workdir0.txt workdir2.txt <--- 全ての補完候補に「.txt」を付加
.inputrc.txt sample2.txt.txt sample.sh.txt .vimrc.txt workdir1.txt
$ complete -W 'aaa bbb ccc' echo <--- 「echo」コマンドの補完の生成を指定した文字列を分割した単語に指定
$ echo [TAB] <--- 「complete」実行後のコマンド「echo」に対する補完を確認
aaa bbb ccc <--- 文字列分割の結果から成る補完候補リスト
$ complete -f echo
$ echo [TAB] <--- ファイル名による補完候補を確認
.bash_history sample1.txt sample3.txt .viminfo workdir0/ workdir2/
.inputrc sample2.txt sample.sh .vimrc workdir1/
$ complete -r <--- 補完設定を消去
$ complete -f -X '.*' echo <--- 「echo」コマンドの補完の生成をファイル名に指定し、「.」から始まる候補を除外
$ echo [TAB] <--- 「complete」実行後のコマンド「echo」に対する補完を確認
sample1.txt sample2.txt sample3.txt sample.sh workdir0/ workdir1/ workdir2/ <--- 「.」から始まる候補を除外
$ jobs <--- 現在のジョブを確認(結果 : 無)
$ complete -j echo
$ echo [TAB] <--- 補完候補が無いことを確認(確認後行消去)
$ complete -r <--- 補完設定を消去
$ complete -j -o default echo <--- 補完候補が生成されない場合に、readlineのデフォルトのファイル名による補完を指定
$ echo [TAB] <--- 「complete」実行後のコマンド「echo」に対する補完を確認
.bash_history sample1.txt sample3.txt .viminfo workdir0/ workdir2/ <--- ファイル名から成る補完候補リスト
.inputrc sample2.txt sample.sh .vimrc workdir1/
$ jobs <--- 現在のジョブを確認(結果 : 無)
$ complete -j -o dirnames echo <--- 補完候補が生成されない場合に、ディレクトリ名による補完を指定
$ echo [TAB] <--- 「complete」実行後のコマンド「echo」に対する補完を確認
workdir0/ workdir1/ workdir2/ <--- ディレクトリ名から成る補完候補リスト
$ complete -W '/a/aa "bb cc" dd"d' echo <--- 「-o filenames」を使用せずにcompleteを実行
$ echo [TAB] <--- 補完候補を確認
/a/aa bb cc ddd
上記3単語の一文字目入力時の補完結果
echo /a/aa
echo bb cc
echo ddd <--- ダブルクォートは除去される
$ complete -r <--- 補完設定を削除
$ complete -W '/a/aa "bb cc" dd"d' -o filenames echo <--- 補完候補がファイル名である事を指定
$ echo [TAB] <--- 補完候補を確認
aa bb cc ddd <--- 文字列未入力時の補完候補リスト
単語の一文字目入力時の補完結果(リスト出力と異なる補完結果)
echo /a/aa
echo bb\ cc <--- 空白にはエスケープ文字を付加
echo ddd
$ complete -f echo <--- 「-o nosort」を使用せずにcompleteを実行
$ echo [TAB] <--- 補完候補を確認
.bash_history sample1.txt sample3.txt .viminfo workdir0/ workdir2/ <--- ソートされた補完候補リスト(先頭の「.」の考慮は無し)
.inputrc sample2.txt sample.sh .vimrc workdir1/
$ complete -r <--- 補完設定を削除
$ complete -f -o nosort echo <--- 「-o nosort」を追加して実行
$ echo [TAB] <--- 補完候補を確認
workdir2/ workdir1/ .bash_history .vimrc sample3.txt sample2.txt <--- ソートせずに補完候補リストを生成
sample.sh .viminfo sample1.txt .inputrc workdir0/
$ complete -b echo <--- 「-o plusdirs」を使用せずにcompleteを実行
$ echo [TAB] <--- 補完候補を確認
. break complete echo false history mapfile readarray source type wait <--- -bオプションによる組み込みコマンドからなる補完候補リスト
: builtin compopt enable fc jobs popd readonly suspend typeset
[ caller continue eval fg kill printf return test ulimit
alias cd declare exec getopts let pushd set times umask
bg command dirs exit hash local pwd shift trap unalias
bind compgen disown export help logout read shopt true unset
$ complete -r <--- 補完設定を削除
$ complete -b -o plusdirs echo <--- 「-o nosort」を追加して実行
$ echo [TAB] <--- 補完候補を確認
./ break complete echo false history mapfile readarray source type wait
: builtin compopt enable fc jobs popd readonly suspend typeset workdir0/ <--- ディレクトリ名の補完候補が追加されている
[ caller continue eval fg kill printf return test ulimit workdir1/
alias cd declare exec getopts let pushd set times umask workdir2/
bg command dirs exit hash local pwd shift trap unalias
bind compgen disown export help logout read shopt true unset
(12)
現在の補完オプションを変更
実行結果
$ complete -j echo <--- コマンド「echo」の補完の生成をジョブ名に指定
$ complete -p <--- 現在の補完設定を確認
complete -j echo
$ compopt -o dirnames echo <--- コマンド「echo」の補完に「-o dirnames」オプションを追加
$ complete -p <--- 現在の補完設定を確認
complete -o dirnames -j echo
$ compopt +o dirnames echo <--- 設定中の「-o dirnames」オプションを削除
$ complete -p <--- 現在の補完設定を確認
complete -j echo
(13)
引数で指定するループの先頭から実行をそのまま継続
1 : 現在のループ
2 : 1つ上のループ
︙
1 : 現在のループ
2 : 1つ上のループ
︙
サンプルファイル(sample.sh)
#!/bin/bash
# ループ用配列
declare -a samp1=("1a" "1b" "1c" "1d")
declare -a samp2=("2a" "2b" "2c" "2d")
# ループ1
for a in ${samp1[@]}
do
# ループ2
for b in ${samp2[@]}
do
if [[ $a == "1b" ]]; then
if [[ $b == "2c" ]]; then
# [ループ2]を次のループから再開
continue
fi
fi
echo "$a --- $b"
if [[ $a == "1c" ]]; then
# 引数に2を指定することで[ループ1]を次のループから再開
continue 2
fi
done
# [ループ2]の完走後改行
echo
done
実行結果
$ ./sample.sh
1a --- 2a
1a --- 2b
1a --- 2c
1a --- 2d
1b --- 2a
1b --- 2b
1b --- 2d <--- 「1b --- 2c」は「ループ2」echoコマンド直前で次のループへ移行で出力されない
1c --- 2a <--- 「1c」で「ループ1」は「ループ2」途中で次のループへ移行
1d --- 2a
1d --- 2b
1d --- 2c
1d --- 2d
(14)
変数の宣言と属性の付与
$ declare -p <--- オプション以外の引数無し
declare -- BASH="/bin/bash" <--- 全シェル変数を表示
declare -r BASHOPTS="checkwinsize:cmdhist:complete_fullquote:expand_aliases:...
declare -i BASHPID
︙
$ declare -p HOME <--- 引数がシェル変数名
declare -x HOME="/home/testusr" <--- 該当シェル変数のみの表示
$ function aa_samplefunc { echo aa; } <--- テスト用関数の作成
$ function bb_samplefunc { echo bb; } <--- 〃
$ function cc_samplefunc { echo cc; } <--- 〃
$ declare -f <--- 「-fオプション」を実行
aa_samplefunc () <--- シェル関数の関数定義を表示
{
echo aa
}
bb_samplefunc ()
{
echo bb
}
cc_samplefunc ()
{
echo cc
}
$ function aa_samplefunc { echo aa; } <--- テスト用関数の作成
$ function bb_samplefunc { echo bb; } <--- 〃
$ function cc_samplefunc { echo cc; } <--- 〃
$ declare -F <--- 「-Fオプション」を実行
declare -f aa_samplefunc <--- シェル関数の関数名と属性を表示
declare -f bb_samplefunc
declare -f cc_samplefunc
サンプルファイル(sample.sh)
#!/bin/bash
sample_func ()
{
# -gオプション無しで宣言
declare samp1="aaa"
# -gオプション有りで宣言
declare -g samp2="bbb"
echo "関数内 -gオプション無し samp1 : $samp1"
echo "関数内 -gオプション有り samp2 : $samp2"
}
echo "シェル関数実行前 -gオプション無し samp1 : $samp1"
echo "シェル関数実行前 -gオプション有り samp2 : $samp2"
echo
sample_func
echo
echo "シェル関数実行後 -gオプション無し samp1 : $samp1"
echo "シェル関数実行後 -gオプション有り samp2 : $samp2"
実行結果
$ ./sample.sh
シェル関数実行前 -gオプション無し samp1 : <--- declare実行前、変数は無効
シェル関数実行前 -gオプション有り samp2 :
関数内 -gオプション無し samp1 : aaa
関数内 -gオプション有り samp2 : bbb
シェル関数実行後 -gオプション無し samp1 : <--- -gオプション無しの変数は関数内ローカルスコープ
シェル関数実行後 -gオプション有り samp2 : bbb <--- -gオプション有りの変数はグローバルスコープ
サンプルファイル(sample.sh)
#!/bin/bash
sample_func ()
{
# -Iオプション無しで宣言
declare samp1
# -Iオプション有りで宣言
declare -I samp2
echo "関数内 -Iオプション無し samp1 : $samp1"
echo "関数内 -Iオプション有り samp2 : $samp2"
}
samp1="aaa"
samp2="bbb"
echo "samp1 : $samp1"
echo "samp2 : $samp2"
echo
sample_func
実行結果
$ ./sample.sh
samp1 : aaa
samp2 : bbb
関数内 -Iオプション無し samp1 : <--- -Iオプション無しの場合は関数外の同名変数の影響は無し
関数内 -Iオプション有り samp2 : bbb <--- -Iオプション有りの場合は関数外の同名変数の値を継承
$ declare -l sample1="AbCdE" <--- -lオプションで小文字指定
$ declare -p sample1
declare -l sample1="abcde" <--- すべて小文字に変換される
$ sample1="FgH" <--- 値を再代入
$ echo $sample1
fgh <--- 小文字属性は継続
サンプルファイル(sample.sh)
#!/bin/bash
declare -a sample1=("aa" "bb" "cc")
declare -n sample12=sample1[2]
echo "\$sample12 = $sample12"
sample12="dd"
declare -p sample1
実行結果
$ ./sample.sh
$sample12 = cc <--- 名前参照により配列sample1[2]の値を参照
declare -a sample1=([0]="aa" [1]="bb" [2]="dd") <--- 名前参照属性の変数への代入は、参照元変数の値の変更となる
$ declare -r sample_r="ro" <--- 変数「sample_r」を読み取り専用で宣言
$ sample_r="sample"
bash: sample_r: readonly variable <--- 読み取り専用変数への代入はエラー
$ unset sample_r
bash: unset: sample_r: cannot unset: readonly variable <--- 読み取り専用変数のunsetもエラー
$ exit <--- ログアウト
exit
$ su testusr
Password:
$ declare -p sample_r
bash: declare: sample_r: not found <--- 再ログイン後は読み取り専用変数が消滅
$ declare -u sample1="AbCdE" <--- -uオプションで大文字指定
$ declare -p sample1
declare -u sample1="ABCDE" <--- すべて大文字に変換される
$ sample1="FgH" <--- 値を再代入
$ echo $sample1
FGH <--- 大文字属性は継続
サンプルファイル(sample.sh)
#!/bin/bash
declare -p sample1
declare -p sample2
実行結果
$ sample1="aa" <--- 変数に値を代入
$ declare -x sample2="bb"
$ echo $sample1 <--- 値の格納を確認
aa
$ echo $sample2 <--- 値の格納を確認
bb
$ ./sample.sh <--- サンプルコードを実行
./sample.sh: line 3: declare: sample1: not found <--- -xオプションが無い場合はコマンド内では存在しない
declare -x sample2="bb" <--- エクスポートされコマンド内でも使用可能
$ declare -x sample1="aa" <--- エクスポート属性を付与する宣言
$ declare -p sample1
declare -x sample1="aa"
$ declare +x sample1="aa" <--- オプションに「+」を使用して再びdeclareを実行
$ declare -p sample1
declare -- sample1="aa" <--- エクスポート属性が削除されている
(15)
ディレクトリスタックの表示・操作
$ dirs <--- ディレクトリスタックを一覧表示
~ <--- 空のディレクトリスタック
$ pushd testdir/ <--- ディレクトリスタックにディレクトリを追加・移動
~/testdir ~
$ pushd workdir1/
~/testdir/workdir1 ~/testdir ~
$ pushd workdir2/
~/testdir/workdir1/workdir2 ~/testdir/workdir1 ~/testdir ~
$ pushd workdir3/
~/testdir/workdir1/workdir2/workdir3 ~/testdir/workdir1/workdir2 ~/testdir/workdir1 ~/testdir ~
$ dirs <--- ディレクトリスタックを一覧表示
~/testdir/workdir1/workdir2/workdir3 ~/testdir/workdir1/workdir2 ~/testdir/workdir1 ~/testdir ~
$ popd <--- ディレクトリスタックから先頭のディレクトリを削除。変わってリスト先頭となったディレクトリへ移動
~/testdir/workdir1/workdir2 ~/testdir/workdir1 ~/testdir ~
$ popd
~/testdir/workdir1 ~/testdir ~
$ popd
~/testdir ~
$ popd
~
$ dirs <--- ディレクトリスタックを一覧表示
~
pushd、popdコマンド実行時にもdirsを実行
$ dirs <--- ディレクトリスタックを一覧表示
~/testdir/workdir1/workdir2/workdir3 ~/testdir/workdir1/workdir2 ~/testdir/workdir1 ~/testdir ~
$ dirs -c <--- ディレクトリスタックをクリア
$ dirs <--- ディレクトリスタックを一覧表示
~/testdir/workdir1/workdir2/workdir3 <--- クリア後はカレントディレクトリがスタックの最初のディレクトリとなる
$ pwd <--- カレントディレクトリを確認
/home/testusr/testdir/workdir1/workdir2/workdir3
$ dirs <--- デフォルトの一覧表示(ホームディレクトリはチルダ使用)
~/testdir/workdir1/workdir2/workdir3 ~/testdir/workdir1/workdir2 ~/testdir/workdir1 ~/testdir ~
$ dirs -l <--- フルパス名を使用した一覧表示
/home/testusr/testdir/workdir1/workdir2/workdir3 /home/testusr/testdir/workdir1/workdir2 /home/testusr/testdir/workdir1 /home/testusr/testdir /home/testusr
$ dirs -p <--- ディレクトリスタックのエントリを行毎に分割して表示
~/testdir/workdir1/workdir2/workdir3
~/testdir/workdir1/workdir2
~/testdir/workdir1
~/testdir
~
$ dirs -v <--- ディレクトリスタックのエントリにスタック内のインデックスを付加して行毎に分割して表示
0 ~/testdir/workdir1/workdir2/workdir3
1 ~/testdir/workdir1/workdir2
2 ~/testdir/workdir1
3 ~/testdir
4 ~
$ dirs <--- オプションなしでdirsを実行
~/testdir/workdir1/workdir2/workdir3 ~/testdir/workdir1/workdir2 ~/testdir/workdir1 ~/testdir ~
$ dirs -v <--- スタック内のインデックスを表示
0 ~/testdir/workdir1/workdir2/workdir3
1 ~/testdir/workdir1/workdir2
2 ~/testdir/workdir1
3 ~/testdir
4 ~
$ dirs +1 <--- オプションなしのdirs表示の左から数えて1番目(0~)のエントリを表示
~/testdir/workdir1/workdir2
$ dirs -1 <--- オプションなしのdirs表示の右から数えて1番目(0~)のエントリを表示
~/testdir
(16)
引数の出力
$ echo "引数1"
引数1 <--- 引数を出力した後改行を出力
$ echo "引数2" ~
引数2 /home/testusr <--- 展開、クォート除去後出力
$ echo 引数 3 "引数 3"
引数 3 引数 3 <--- クォートされていない空白は区切り文字として処理
$ echo -n "引数 " ; echo "改行" <--- -nオプションで改行無しで出力
引数 改行
サンプルファイル(sample.sh)
#!/bin/bash
echo 'エスケープ文字の出力オプション -e'
echo
echo '「\b」 バックスペース'
echo -e 'ab\bcd'
echo
echo '「\c」 以降の出力を停止'
echo -e 'ab\ccd'
echo '「ここは次のechoによる出力」'
echo
echo '「\e、\E」 エスケープ文字'
echo -e 'ab\e[4m\e[7m\e[32mcd\e[0m'
echo
echo '「\n」 改行'
echo -e 'ab\ncd'
echo
echo '「\t」 水平タブ'
echo -e 'ab\tcd'
echo
echo '「\v」 垂直タブ'
echo -e 'ab\vcd'
echo
echo '「\\」 バックスラッシュ'
echo -e 'ab\\cd'
echo
echo '「\0nnn」 8進数nnnを値とする8ビット文字'
echo -e 'ab \0060 cd'
echo
echo '「\xHH」 16進数HHを値とする8ビット文字'
echo -e 'ab \x30 cd'
echo
echo '「\uHHHH」 16進数HHHHを値とするUnicode文字'
echo -e 'ab \uFF10 cd'
echo
echo '「\UHHHHHHHH」 16進数HHHHHHHHを値とするUnicode文字'
echo -e 'ab \U0000FF10 cd'
echo
実行結果
$ ./sample.sh
エスケープ文字の出力オプション -e
「\b」 バックスペース
acd <--- バックスペースにより「b」を削除
「\c」 以降の出力を停止
ab「ここは次のechoによる出力」 <--- 「\c」以降の文字は出力されない。改行も付加されない
「\e、\E」 エスケープ文字
abcd <--- ASCIIエスケープ文字により、文字「cd」は文字色(緑色)・文字色反転・下線に加工される
「\n」 改行
ab
cd
「\t」 水平タブ
ab cd
「\v」 垂直タブ
ab
cd
「\\」 バックスラッシュ
ab\cd <--- バックスラッシュそのものを出力
「\0nnn」 8進数nnnを値とする8ビット文字
ab 0 cd <--- 文字コード「\0060」
「\xHH」 16進数HHを値とする8ビット文字
ab 0 cd <--- 文字コード「\x30」
「\uHHHH」 16進数HHHHを値とするUnicode文字
ab 0 cd <--- 文字コード「\uFF10」
「\UHHHHHHHH」 16進数HHHHHHHHを値とするUnicode文字
ab 0 cd <--- 文字コード「\U0000FF10」
(17)
組み込みシェルコマンドの有効・無効を設定
サンプルファイル(jobs)
#!/bin/bash
echo "jobs(シェルスクリプト)"
実行結果
$ jobs <--- パス指定無しの場合は組み込みシェルコマンド「jobs」実行。アクティブジョブ無しで出力無し
$ ./jobs <--- パス指定でカレントディレクトリの「jobs」スクリプト実行
jobs(シェルスクリプト) <--- echoによる出力
$ echo $PATH <--- シェル変数PATHの確認
/bin:/usr/bin
$ PATH="$PATH":~ <--- シェル変数PATHにカレントディレクトリを追加
$ echo $PATH
/bin:/usr/bin:/home/testusr <--- 追加を確認
$ enable -n jobs <--- 「-nオプション」で組み込みシェルコマンド「jobs」無効化
$ jobs <--- パス指定無しでコマンド「jobs」実行
jobs(シェルスクリプト) <--- サンプルファイルの「jobs」スクリプトが実行される
$ enable jobs <--- 「オプション無し」で組み込みシェルコマンド「jobs」有効化
$ jobs <--- 組み込みシェルコマンド「jobs」が実行される。アクティブジョブが無く出力無し
$
実行結果
$ enable -n jobs <--- 「-nオプション」でみ込みシェルコマンド「jobs」無効化
$ enable
enable . <--- 現在有効な組み込みシェルコマンドの一覧を表示
enable :
enable [
enable alias
︙
$ enable -n
enable -n jobs <--- 現在無効な組み込みシェルコマンドの一覧を表示
$ enable -a
enable .<--- 有効・無効を合わせた組み込みシェルコマンドの一覧を表示
enable :
enable [
enable alias
︙
enable history
enable -n jobs <--- 無効なコマンド
enable kill
︙
(18)
引数を読み込み1つのコマンドに連結後、コマンドを読み込み実行
サンプルファイル(sample.sh)
#!/bin/bash
str="\$1 = $1"
# 引数を関数名にして関数を宣言
eval $1 ' () { echo $str ; echo ; }'
# 引数の関数を実行
$1
# 関数の定義を確認
declare -f $1
実行結果(1)
$ ./sample.sh aa
$1 = aa <--- 「eval」で定義された引数で指定された関数を実行
aa () <--- 定義された関数
{
echo $str;
echo
}
実行結果(2)
サンプルコードから「eval」を削除して実行
サンプルコードから「eval」を削除して実行
$ ./sample.sh aa
./sample.sh: line 7: aa: command not found <--- 行頭の「aa」がコマンドと解釈されエラーとなる
./sample.sh: line 10: aa: command not found
(19)
実行結果
$ sleep 10 <--- コマンドsleepのみで実行
$ exec sleep 10 <--- execの引数としてsleepを実行
上記コマンド終了と共にログアウト(bash終了)
********** 別端末にて実行 **********
$ ps -u testusr
PID TTY TIME CMD
680 pts/0 00:00:00 bash
725 pts/1 00:00:00 bash
733 pts/1 00:00:00 ps
$ ps -u testusr <--- 「sleep 10」起動後に実行
PID TTY TIME CMD
680 pts/0 00:00:00 bash
725 pts/1 00:00:00 bash
734 pts/0 00:00:00 sleep <--- 新しいプロセスとして起動
735 pts/1 00:00:00 ps
$ ps -u testusr
PID TTY TIME CMD
680 pts/0 00:00:00 bash
725 pts/1 00:00:00 bash
737 pts/1 00:00:00 ps
$ ps -u testusr <--- 「exec sleep 10」起動後に実行
PID TTY TIME CMD
680 pts/0 00:00:00 sleep <--- bashが同じPIDでsleepに置き換わる
725 pts/1 00:00:00 bash
739 pts/1 00:00:00 ps
$ ps -u testusr
PID TTY TIME CMD <--- sleep終了で元のプロセス自体が終了
725 pts/1 00:00:00 bash
741 pts/1 00:00:00 ps
実行結果
$ 3> sample.txt <--- exec無しでリダイレクトを指定
$ echo "sample 1" >&3 <--- 前行でリダイレクト指定したファイルディスクリプタへ出力
bash: 3: Bad file descriptor <--- 不正なファイルディスクリプタに関するエラー発生
$ exec 3> sample.txt <--- execの引数としてリダイレクトを指定
$ date ; date >&3 <--- 標準出力とfd3へ日時を出力
Mon 7 Nov 18:30:49 JST 2022 <--- 標準出力への出力
$ cat sample.txt
Mon 7 Nov 18:30:49 JST 2022 <--- fd3(sample.txt)への出力
$ exec 3>&- <--- fd3を閉じる
実行結果
(サブシェル環境で実行)
(サブシェル環境で実行)
$ (exec printenv) <--- -cオプション無しで実行
SHELL=/bin/bash <--- 設定されている環境変数
XDG_CONFIG_DIRS=/etc/xdg/
PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
︙
$ (exec -c printenv) <--- -cオプション有りで実行
$ <--- 設定されている環境変数は無し
(20)
シェルを指定したステータスと共に終了させる
実行結果
$ ( echo "sample 1" ; exit ) ; echo "終了ステータス : $?"
sample 1
終了ステータス : 0 <--- 引数無しの場合は、最後に実行されたコマンドのステータス
$ ( echo "sample 2" ; exit 1 ) ; echo "終了ステータス : $?"
sample 2
終了ステータス : 1 <--- 指定したステータス
$ ( echo "sample 3" ; exit 2 ) ; echo "終了ステータス : $?"
sample 3
終了ステータス : 2 <--- 〃
(21)
指定した変数・関数は以後実行されるコマンドの環境に自動的にエクスポートするようにマークされる
実行結果
$ samplevar="test" <--- 変数を定義
$ declare -p | grep samplevar <--- 定義を確認
declare -- samplevar="test"
$ printenv | grep samplevar <--- 環境変数を確認。出力無し
$ export samplevar <--- エクスポート指定
$ printenv | grep samplevar <--- 再度環境変数を確認
samplevar=test <--- 出力有り
$ export -n samplevar <--- エクスポート指定を解除
$ printenv | grep samplevar <--- 環境変数を確認。出力無し
$
実行結果
$ export <--- オプション・変数名・関数名無し
declare -x HISTIGNORE="&:[bf]g:exit" <--- エクスポートされた全ての変数のリスト
declare -x HISTSIZE="1000"
declare -x HOME="/home/testusr"
︙
$ export -p <--- -p オプション
declare -x HISTIGNORE="&:[bf]g:exit" <--- 上記と同じ結果
declare -x HISTSIZE="1000"
declare -x HOME="/home/testusr"
︙
実行結果
$ function aa_samplefunc { echo aa; } <--- テスト用関数の作成
$ function bb_samplefunc { echo bb; } <--- 〃
$ function cc_samplefunc { echo cc; } <--- 〃
$ export -f <--- エクスポートされている関数の確認。出力無し
$ export -f aa_samplefunc <--- テスト用関数のエクスポート
$ export -f bb_samplefunc <--- 〃
$ export -f cc_samplefunc <--- 〃
$ export -f <--- エクスポートされている関数の確認
aa_samplefunc ()
{
echo aa
}
declare -fx aa_samplefunc
bb_samplefunc ()
{
echo bb
}
declare -fx bb_samplefunc
cc_samplefunc ()
{
echo cc
}
declare -fx cc_samplefunc
(22)
履歴リスト上のコマンドを編集・再実行
実行結果
$ echo "sample1" <--- テスト履歴用に実行
sample1
$ echo "sample2" <--- 〃
sample2
$ echo "sample3" <--- 〃
sample3
$ fc <--- fc実行時、vi(デフォルト)が起動し編集保存したコマンドを実行
echo "sample4" <--- 起動したviで「3」を「4」に変更して保存。編集内容がechoされる
sample4 <--- vi終了後、コマンド実行
$ fc -4 -1 <--- 履歴リストの4つ前から1つ前までのコマンドを編集・再実行
echo "sample5" <--- 「1 2 3 4」をそれぞれ「5 6 7 8」に変更・保存・実行
sample5
echo "sample6"
sample6
echo "sample7"
sample7
echo "sample8"
sample8
実行結果
(上記「オプション無し」の出力結果の続きより)
(上記「オプション無し」の出力結果の続きより)
$ fc -l -8 -1 <--- 「-l」オプションで履歴リストを番号付きで出力
502 echo "sample1"
503 echo "sample2"
504 echo "sample3"
505 echo "sample4"
506 echo "sample5"
507 echo "sample6"
508 echo "sample7"
509 echo "sample8"
$ fc -ln -8 -1 <--- 「-n」オプション追加で履歴リストを番号無しで出力
echo "sample2"
echo "sample3"
echo "sample4"
echo "sample5"
echo "sample6"
echo "sample7"
echo "sample8"
fc -l -8 -1
$ fc -lr -8 -1 <--- 「-r」オプション追加で履歴リストを逆順で出力
511 fc -ln -8 -1
510 fc -l -8 -1
509 echo "sample8"
508 echo "sample7"
507 echo "sample6"
506 echo "sample5"
505 echo "sample4"
504 echo "sample3"
実行結果
$ date +%Y%m <--- テスト用コマンドとして「date」を実行
202211
$ echo "sample1" <--- テスト用コマンドとして「echo」を実行
sample1
$ fc -s '1'='_a' <--- 引数としてのコマンドを指定せずに「-s」オプションを実行
echo "sample_a" <--- 直前の「echo」の引数を置換して再実行
sample_a
$ fc -s '%m'='%m%d' date <--- 引数コマンドとして「date」を指定して「-s」オプションを実行
date +%Y%m%d <--- 「date」で始まる最後のコマンドに指定の置換を行い再実行
20221109
(24)
オプション文字列からなる位置パラメータまたはコマンド引数を処理するために使用
サンプルファイル(sample.sh)
#!/bin/bash
echo "オプション文字列 ---> ab:c:"
echo "引数無しオプション ---> a"
echo "引数有りオプション ---> b c"
echo
echo "位置パラメータ使用 ---> \$@ = $@"
while getopts ab:c: name
do
case $name in
a) echo "オプション a";;
b) echo "オプション b OPTARG = $OPTARG";;
c) echo "オプション c OPTARG = $OPTARG";;
esac
done
echo
echo "OPTIND = $OPTIND"
OPTIND=1
echo "リセット後 OPTIND = $OPTIND"
echo
echo 'コマンド引数使用 ---> -a -b 1 -c 3 -a -c x -b 2'
while getopts ab:c: name -a -b 1 -c 3 -a -c x -b 2
do
case $name in
a) echo "オプション a";;
b) echo "オプション b OPTARG = $OPTARG";;
c) echo "オプション c OPTARG = $OPTARG";;
esac
done
実行結果
$ ./sample.sh -a -b s -c sample <--- 引数を付けてサンプルコードを実行
オプション文字列 ---> ab:c:
引数無しオプション ---> a
引数有りオプション ---> b c
位置パラメータ使用 ---> $@ = -a -b s -c sample <--- 位置パラメータにはコード実行時の引数
オプション a
オプション b OPTARG = s <--- オプション引数はOPTARGに格納される
オプション c OPTARG = sample
OPTIND = 6
リセット後 OPTIND = 1 <--- getoptsの読み取り位置をリセット(必須)
コマンド引数使用 ---> -a -b 1 -c 3 -a -c x -b 2 <--- getoptsのオプション文字列を使用してループ
オプション a
オプション b OPTARG = 1
オプション c OPTARG = 3
オプション a
オプション c OPTARG = x
オプション b OPTARG = 2
(25)
コマンドへのパスを記憶
実行結果
$ hash <--- オプション・コマンド指定無しで実行
hits command
1 /bin/ls <--- 記憶されているコマンドのパスを表示
1 /bin/cat
$ hash cat <--- 記憶されているコマンドを指定して実行
$ hash
hits command
1 /bin/ls
0 /bin/cat <--- 指定したコマンドの情報を更新。hitsの値は0にリセット
$ hash date <--- 記憶されていないコマンドを指定して実行
$ hash
hits command
1 /bin/ls
0 /bin/date <--- hitsの値0で新規に追加
0 /bin/cat
サンプルファイル(cat.sh)
#!/bin/bash
echo "********** test cat **********"
cat $0
実行結果
$ hash <--- 現在記憶されているパスを確認
hits command
1 /bin/ls
0 /bin/date
1 /bin/cat
$ hash -p /home/testusr/cat.sh cat <--- -pオプションでコマンドのフルファイル名を指定
$ hash
hits command
1 /bin/ls
0 /bin/date
0 /home/testusr/cat.sh <--- 指定のフルファイル名(catコマンド)
$ cat cat.sh <--- catコマンドを実行
********** test cat ********** <--- catコマンドとしてサンプルコードが実行される
#!/bin/bash
echo "********** test cat **********"
cat $0
実行結果
$ hash <--- 記憶されているコマンドを確認
hits command
1 /bin/ls
0 /bin/date
0 /bin/cat
$ hash -d cat <--- -dオプションでコマンドcatを指定
$ hash
hits command
1 /bin/ls <--- コマンドcatが削除されている
0 /bin/date
$ hash -r <--- -dオプションで実行
$ hash
hash: hash table empty <--- 全てのコマンドが削除される
実行結果
$ hash <--- 記憶されているコマンドを確認
hits command
1 /bin/ls
1 /bin/date
1 /bin/cat
$ hash -t date <--- -tオプションでコマンドdateを指定
/bin/date <--- 指定されたコマンドのフルパスを出力
$ hash -t date cat <--- -tオプションで複数のコマンドを指定
date /bin/date <--- 指定されたコマンドの名前とフルパスを出力
cat /bin/cat
$ hash -l <--- -lオプションで実行
builtin hash -p /bin/ls ls <--- 記憶されているコマンドに関する情報を再利用可能な形式で出力
builtin hash -p /bin/date date
builtin hash -p /bin/cat cat
(26)
組み込みシェルコマンドに関する情報を表示
実行結果
$ help -d help <--- -dオプションで対象コマンドとして「help」を指定
help - Display information about builtin commands. <--- 簡単な説明文を表示
$ help -m help <--- -mオプションで対象コマンドとして「help」を指定
NAME <--- manページのような解説を表示
help - Display information about builtin commands.
SYNOPSIS
help [-dms] [pattern ...]
DESCRIPTION
Display information about builtin commands.
Displays brief summaries of builtin commands. If PATTERN is
specified, gives detailed help on all commands matching PATTERN,
otherwise the list of help topics is printed.
︙
$ help -s help <--- -sオプションで対象コマンドとして「help」を指定
help: help [-dms] [pattern ...] <--- 使用方法を表示
(27)
履歴(ヒストリ)を操作
実行結果
$ history <--- コマンド名のみで実行
1 history <--- 全履歴リストを出力
2 ls -l
3 cat sample.sh
4 history
$ history 3 <--- コマンドと数値で実行
3 cat sample.sh <--- 数値で指定した行数を出力
4 history
5 history 3 <--- 履歴リストの最後は最後に実行したコマンド
実行結果
$ history <--- 現在の履歴リストの内容
1 ls -l
2 cat sample.txt
3 history
$ history -c <--- 履歴リストを削除
$ history
1 history <--- 直前(削除後)に実行したコマンドのみ存在
実行結果(1)
$ history <--- 全履歴リストを確認
1 history
2 ls -l
3 cat sample.sh
4 pwd
5 history
$ history -d 2 <--- 削除位置として「2」を指定
$ history
1 history
2 cat sample.sh <--- 履歴リストの最初から2番目の位置にあったコマンド履歴が削除される
3 pwd
4 history
5 history -d 2
6 history
実行結果(2)
$ history <--- 全履歴リストを確認
1 history
2 cat sample.sh
3 pwd
4 history
$ history -d -2 <--- 削除位置として「-2」を指定
$ history
1 history
2 cat sample.sh
3 pwd <--- 削除実行のコマンド(行番号5)を-1として、-2の位置にあったコマンド履歴が削除される
4 history -d -2
5 history
実行結果(3)
$ history <--- 全履歴リストを確認
1 history
2 cat sample.sh
3 pwd
4 history
5 ls -l
6 history
$ history -d 2-4 <--- 削除位置として「2」~「4」を指定
$ history
1 history
2 ls -l <--- 履歴リストの最初から2~4番目の位置にあったコマンド履歴が削除される
3 history
4 history -d 2-4
5 history
実行結果
$ history <--- 全履歴リストを確認
1 ls -l
2 history
3 cat sample.sh
4 history
5 cat .bash_history
6 history
$ echo "sample1" <--- サンプル用コマンド実行
sample1
$ echo "sample2" <--- 〃
sample2
$ cat .bash_history <--- -aオプション実行前の履歴ファイルの内容
history -r sample_history
ls -l
history
cat sample.sh
history
history -w
$ history -a <--- -aオプションでhistoryコマンドを実行
$ cat .bash_history <--- -aオプション実行後の履歴ファイルの内容
history -r sample_history
ls -l
history
cat sample.sh
history
history -w
history <--- 着色部は追加されたヒストリ
cat .bash_history
history
echo "sample1"
echo "sample2"
cat .bash_history
history -a
実行結果
(sample_historyは-wオプションにより書き込み)
(sample_historyは-wオプションにより書き込み)
$ history <--- 現在の履歴リストを確認
1 ls -l
2 history
3 cat sample.sh
4 history
5 history -w
6 cd
7 history
$ cat sample_history <--- サンプル用履歴ファイルの確認
ls -l
history
cat sample.sh
history
history -w
echo "sample1"
echo "sample2"
echo "sample3"
history -w sample_history
$ history -n sample_history <--- サンプル用履歴ファイルの読み込み
$ history
1 ls -l
2 history
3 cat sample.sh
4 history
5 history -w <--- 5行目まではサンプル用履歴ファイルと重複
6 cd
7 history
8 cat sample_history
9 history -n sample_history
10 echo "sample1" <--- 着色部は読み込まれたヒストリ
11 echo "sample2"
12 echo "sample3"
13 history -w sample_history
14 history
実行結果
(sample_historyは-wオプションにより書き込み)
(sample_historyは-wオプションにより書き込み)
$ history <--- 現在の履歴リストを確認
1 ls -l
2 history
3 cat sample.sh
4 history
5 history -w
6 history
7 cd
8 history
$ cat sample_history <--- サンプル用ヒストリファイルの確認
ls -l
history
cat sample.sh
history
history -w
echo "sample1"
echo "sample2"
echo "sample3"
history -w sample_history
$ history -r sample_history <--- サンプル用ヒストリファイルの読み込み
$ history
1 ls -l
2 history
3 cat sample.sh
4 history
5 history -w
6 history
7 cd
8 history
9 cat sample_history
10 history -r sample_history
11 ls -l <--- 着色部は読み込まれたヒストリ
12 history
13 cat sample.sh
14 history
15 history -w
16 echo "sample1"
17 echo "sample2"
18 echo "sample3"
19 history -w sample_history
20 history
実行結果
$ history <--- クリア前の履歴リスト
1 ./sample.sh aa
2 vi sample.sh
︙
644 ls -al
645 history
$ history -c <--- 履歴リストをクリア
$ echo "sample1" <--- サンプル履歴用コマンド
sample1
$ echo "sample2" <--- 〃
sample2
$ echo "sample3" <--- 〃
sample3
$ history -w <--- 履歴リストを書き込み
$ cat .bash_history <--- 履歴ファイルを確認
echo "sample1"
echo "sample2"
echo "sample3"
history -w
$ history -w sample_history <--- 履歴リストを指定ファイルに書き込み
$ cat sample_history <--- 書き込み時に指定したファイルを確認
echo "sample1"
echo "sample2"
echo "sample3"
history -w
cat .bash_history
history -w sample_history
実行結果
$ cat sample1.txt !#:$:s/1/2/ !#:$:s/2/3/ <--- 履歴置換候補があるコマンドを入力
cat sample1.txt sample2.txt sample3.txt
sample1.txt ... <--- 履歴置換実行後にコマンドを実行
sample2.txt ...
sample3.txt ...
$ history -p 'cat sample1.txt !#:$:s/1/2/ !#:$:s/2/3/' <--- -pオプションの引数として履歴置換候補があるコマンドを入力
cat sample1.txt sample2.txt sample3.txt <--- 履歴置換結果の出力のみ
$ history 3
28 vi sample3.txt
29 cat sample1.txt sample2.txt sample3.txt
30 history 3 <--- 履歴リストには記録されない
実行結果
$ history <--- 現在の履歴リストを確認
1 echo "sample1"
2 echo "sample2"
3 history
$ history -s 'echo "sample3"' <--- 履歴リストに「echo "sample3」を追加
$ history
1 echo "sample1"
2 echo "sample2"
3 history
4 echo "sample3" <--- 履歴リストに「echo "sample3」が追加される
5 history
コマンド「history -s ...」自体は格納されない
(28)
ジョブに関する情報を表示
実行結果
$ jobs <--- 現在のジョブ状況を確認 - アクティブジョブ無し
$ sleep 10 <--- サンプル用ジョブの実行(1)
^Z <--- ジョブを[Control-z]で停止
[1]+ Stopped sleep 10
$ sleep 60 <--- サンプル用ジョブの実行(2)
^Z <--- ジョブを[Control-z]で停止
[2]+ Stopped sleep 60
$ bg %2 <--- バックグラウンドでジョブ番号2を再開
[2]+ sleep 60 &
$ sleep 11 <--- サンプル用ジョブの実行(3)
^Z <--- ジョブを[Control-z]で停止
[3]+ Stopped sleep 11
$ jobs <--- アクティブジョブ(実行中、停止中)の一覧を出力
[1]- Stopped sleep 10
[2] Running sleep 60 &
[3]+ Stopped sleep 11
$ jobs <--- ジョブ番号2が終了後実行
[1]- Stopped sleep 10
[2] Done sleep 60 <--- ジョブ番号2は終了
[3]+ Stopped sleep 11
$ jobs <--- 再度実行
[1]- Stopped sleep 10
[3]+ Stopped sleep 11 <--- ジョブ番号2の出力は無し
実行結果
$ jobs <--- オプション無しの出力
[1]- Stopped sleep 10
[2] Running sleep 60 &
[3]+ Stopped sleep 11
$ jobs -l
[1]- 346 Stopped sleep 10 <--- プロセスIDの情報が付加される
[2] 347 Running sleep 60 &
[3]+ 348 Stopped sleep 11
実行結果
$ jobs <--- オプション無しの出力
[1]- Stopped sleep 10
[2] Running sleep 60 &
[3]+ Stopped sleep 11
$ jobs -r
[2] Running sleep 60 & <--- 実行中のジョブのみ出力
実行結果
$ jobs <--- オプション無しの出力
[1]- Stopped sleep 10
[2] Running sleep 60 &
[3]+ Stopped sleep 11
$ jobs -s
[1]- Stopped sleep 10 <--- 停止中のジョブのみ出力
[3]+ Stopped sleep 11
(29)
指定されたプロセスに指定されたシグナルを送信
実行結果
$ kill -l <--- シグナル名の一覧を表示
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX
$ kill -l 1 2
HUP <--- 引数のシグナル番号に対応するシグナルの名前のリスト
INT
$ kill -l 2 130
INT <--- シグナル番号「2」に対応するシグナルの名前
INT <--- シグナルによって終了した プロセスの終了ステータス「130」に対応するシグナルの名前
実行結果
$ jobs <--- 現在のジョブ状況を確認 - アクティブジョブ無し
$ sleep 10m & <--- サンプル用ジョブの実行
[1] 314
$ jobs -l
[1]+ 314 Running sleep 10m & <--- 実行中のプロセス(ジョブ番号 : 1、プロセスID : 314)
$ kill %1 <--- ジョブ番号1のプロセスにSIGTERMを送信
$ jobs -l
[1]+ 314 Terminated sleep 10m <--- ジョブ番号1のプロセスが終了
$ sleep 10m & <--- サンプル用ジョブの実行
[1] 315
$ jobs -l
[1]+ 315 Running sleep 10m & <--- 実行中のプロセス(ジョブ番号 : 1、プロセスID : 315)
$ kill 315 <--- プロセスID 315のプロセスにSIGTERMを送信
$ jobs -l
[1]+ 315 Terminated sleep 10m <--- プロセスID 315のプロセスが終了
実行結果
$ jobs <--- 現在のジョブ状況を確認 - アクティブジョブ無し
$ sleep 10m & <--- サンプル用ジョブの実行
[1] 346
$ kill -s SIGKILL 346 <--- シグナル名に「SIGKILL(キル信号)」を指定して実行
$ jobs
[1]+ Killed sleep 10m <--- 「SIGKILL」によりキル
$ sleep 10m &
[1] 349
$ kill -s 9 349 <--- シグナル番号を指定して実行
$ jobs
[1]+ Killed sleep 10m <--- -sオプションでのシグナル番号の指定も有効
$ sleep 10m &
[1] 350
$ kill -s SIGTERM 350 <--- シグナル名に「SIGTERM(終了信号)」を指定して実行
$ jobs
[1]+ Terminated sleep 10m <--- 「SIGTERM」により終了
実行結果
$ jobs <--- 現在のジョブ状況を確認 - アクティブジョブ無し
$ sleep 10m & <--- サンプル用ジョブの実行
[1] 479
$ kill -n 9 479 <--- シグナル番号に「9(SIGKILL)」を指定して実行
$ jobs
[1]+ Killed sleep 10m <--- 「SIGKILL」によりキル
$ sleep 10m &
[1] 480
$ kill -n SIGKILL 480 <--- シグナル名を指定して実行
$ jobs
[1]+ Killed sleep 10m <--- -nオプションでのシグナル名の指定も有効(マニュアル記載無し)
$ sleep 10m &
[1] 481
$ kill -n 15 481 <--- シグナル番号に「15(SIGTERM)」を指定して実行
$ jobs
[1]+ Terminated sleep 10m <--- 「SIGTERM」により終了
実行結果
$ jobs <--- 現在のジョブ状況を確認 - アクティブジョブ無し
$ sleep 10m & <--- サンプル用ジョブの実行
[1] 256
$ kill -SIGKILL 256 <--- シグナル名に「SIGKILL(キル信号)」を指定して実行
$ jobs
[1]+ Killed sleep 10m <--- 「SIGKILL」によりキル
$ sleep 10m &
[1] 257
$ kill -9 257 <--- シグナル番号を指定して実行
$ jobs
[1]+ Killed sleep 10m <--- 「SIGKILL」によりキル
$ sleep 10m &
[1] 259
$ kill -SIGTERM 259 <--- シグナル名に「SIGTERM(終了信号)」を指定して実行
$ jobs
[1]+ Terminated sleep 10m <--- 「SIGTERM」により終了
(30)
算術式を評価
実行結果
$ nn=1 ; mm=2 ; let nn="$nn + $mm" ; echo $nn <--- letを使用して実行
3 <--- 引数が算術式として評価される
$ nn=1 ; mm=2 ; nn="$nn + $mm" ; echo $nn <--- letを使用せずに実行
1 + 2 <--- 文字列として変数に代入される
(31)
ローカル変数を作成
サンプルファイル(sample.sh)
#!/bin/bash
function samplefunc
{
local a=1 #ローカル変数
b=2
#組み込みシェルコマンドdeclareのオプションをコマンドlocalで使用
local -a c=([0]="a" [1]="b" [2]="c")
echo "*************** samplefunc *******************"
echo "a = $a : b = $b"
echo "$(local)"
echo "**********************************************"
}
a=10
b=20
samplefunc
echo "a = $a : b = $b"
実行結果
$ ./sample.sh
*************** samplefunc *******************
a = 1 : b = 2 <--- 関数内の変数値
declare -- a="1" <--- 組み込みシェルコマンドlocalによるlocal変数に関する出力
declare -a c=([0]="a" [1]="b" [2]="c") <--- 〃
**********************************************
a = 10 : b = 2 <--- 変数bはlocalではないので関数内の代入の影響有り
(32)
ログインシェルを終了
実行結果
$ bash -l <--- ログインシェルとしてbashを起動
testusr [ ~ ]$ logout <--- ログインシェルを終了
$ bash <--- ログインシェルとはせずにbashを起動
$ logout
bash: logout: not login shell: use `exit' <--- ログインシェルではないのでエラー発生
$ exit
exit
(33)
インデックス付き配列変数に行を読み込む
実行結果
$ mapfile
sample_text1 <--- 標準入力(キーボード)から入力
sample_text2 <--- 〃
sample_text3 <--- 〃(次行行頭Ctrl-dでEOF入力にて終了)
$ declare -p MAPFILE <--- 変数MAPFILEを確認(指定無しの場合、変数MAPFILEに読み込まれる)
declare -a MAPFILE=([0]=$'sample_text1\n' [1]=$'sample_text2\n' [2]=$'sample_text3\n')
実行結果
$ mapfile samplearray <--- 変数名「samplearray」を指定
sample_text1
sample_text2
sample_text3
$ declare -p samplearray <--- 変数「samplearray」を確認
declare -a samplearray=([0]=$'sample_text1\n' [1]=$'sample_text2\n' [2]=$'sample_text3\n')
実行結果
$ cat sample.txt <--- サンプル用文字列ファイル
aaa,bbb,ccc <--- 「,」で区切られた文字列。終端は改行ではなく「c」
$ mapfile -d ',' < sample.txt <--- 区切り文字として「,」を指定
$ declare -p MAPFILE <--- 変数MAPFILEを確認
declare -a MAPFILE=([0]="aaa," [1]="bbb," [2]=$'ccc\n') <--- 最後の「c」の後に改行が付加されている
実行結果
$ cat sample.txt <--- サンプル用文字列ファイル
aaa
bbb
ccc
ddd
eee
$ mapfile -n 3 < sample.txt <--- 最大読み込み数に3を指定
$ declare -p MAPFILE
declare -a MAPFILE=([0]=$'aaa\n' [1]=$'bbb\n' [2]=$'ccc\n') <--- 3行まで読み込み
実行結果
$ cat sample.txt <--- サンプル用文字列ファイル
aaa
bbb
ccc
ddd
eee
$ mapfile -O 5 < sample.txt <--- 初期値に5を指定
$ declare -p MAPFILE
declare -a MAPFILE=([5]=$'aaa\n' [6]=$'bbb\n' [7]=$'ccc\n' [8]=$'ddd\n' [9]=$'eee\n') <--- インデックス5から読み込み
$ mapfile -O 2 < sample.txt <--- 初期値に2を指定
$ declare -p MAPFILE
declare -a MAPFILE=([2]=$'aaa\n' [3]=$'bbb\n' [4]=$'ccc\n' [5]=$'ddd\n' [6]=$'eee\n' [7]=$'ccc\n' [8]=$'ddd\n' [9]=$'eee\n') <--- インデックス2から読み込まれるが既存の配列変数はクリアされない
$ mapfile < sample.txt <--- 初期値を指定せずに読み込み
$ declare -p MAPFILE
declare -a MAPFILE=([0]=$'aaa\n' [1]=$'bbb\n' [2]=$'ccc\n' [3]=$'ddd\n' [4]=$'eee\n') <--- 配列変数がクリアされ、インデックス0から読み込まれる
実行結果
$ cat sample.txt <--- サンプル用文字列ファイル
aaa
bbb
ccc
ddd
eee
$ mapfile -s 2 < sample.txt <--- 最初の2行の破棄を指定
$ declare -p MAPFILE
declare -a MAPFILE=([0]=$'ccc\n' [1]=$'ddd\n' [2]=$'eee\n') <--- 「aaa\n」と「bbb\n」は破棄
実行結果
$ cat sample1.txt <--- 改行で区切りのサンプル用文字列ファイル
aaa
bbb
ccc
$ mapfile -t < sample1.txt <--- デフォルトの区切り文字の削除を指定
$ declare -p MAPFILE
declare -a MAPFILE=([0]="aaa" [1]="bbb" [2]="ccc") <--- 改行が削除されている
$ cat sample2.txt
ddd,eee,fff <--- 「,」区切りのサンプル用文字列ファイル
$ mapfile -d ',' -t < sample2.txt <--- 区切り文字を「,」として区切り文字の削除を指定
$ declare -p MAPFILE
declare -a MAPFILE=([0]="ddd" [1]="eee" [2]=$'fff\n') <--- 最後の配列の終端に改行が付加される
$ cat sample3.txt
ggg,hhh,iii, <--- 終端にも「,」がある「,」区切りのサンプル用文字列ファイル
$ mapfile -d ',' -t < sample3.txt
$ declare -p MAPFILE
declare -a MAPFILE=([0]="ggg" [1]="hhh" [2]="iii" [3]=$'\n') <--- 最後の配列の終端の「,」は削除されるが、改行が「,」で区切られて配列として追加される
実行結果
$ cat sample.txt <--- サンプル用文字列ファイル
aaa
bbb
ccc
ddd
eee
$ exec 3<sample.txt <--- fd 3 を「sample.txt」からのリダイレクトとして指定
$ ls -l /proc/self/fd/
total 0
lrwx------ 1 testusr testusr 64 Dec 23 11:41 0 -> /dev/pts/0
lrwx------ 1 testusr testusr 64 Dec 23 11:41 1 -> /dev/pts/0
lrwx------ 1 testusr testusr 64 Dec 23 11:41 2 -> /dev/pts/0
lr-x------ 1 testusr testusr 64 Dec 23 11:41 3 -> /home/testusr/sample.txt <--- fd 3 (「sample.txt」からのリダイレクト)
lr-x------ 1 testusr testusr 64 Dec 23 11:41 4 -> /proc/290/fd
$ mapfile -u 3 <--- 標準入力の代わりに fd 3 を指定
$ declare -p MAPFILE
declare -a MAPFILE=([0]=$'aaa\n' [1]=$'bbb\n' [2]=$'ccc\n' [3]=$'ddd\n' [4]=$'eee\n') <--- 「sample.txt」の内容が読み込まれる
$ exec 3<&- <--- fd 3 を閉じる
$ ls -l /proc/self/fd/
total 0
lrwx------ 1 testusr testusr 64 Dec 23 11:43 0 -> /dev/pts/0
lrwx------ 1 testusr testusr 64 Dec 23 11:43 1 -> /dev/pts/0
lrwx------ 1 testusr testusr 64 Dec 23 11:43 2 -> /dev/pts/0
lr-x------ 1 testusr testusr 64 Dec 23 11:43 3 -> /proc/292/fd
実行結果
$ cat sample.txt <--- サンプル用文字列ファイル
aaa
bbb
ccc
ddd
eee
fff
$ samplefunc() { echo "------- 読み込み配列[$1] = $2 ------------"; } <--- コールバック関数
$ mapfile -t -C samplefunc -c 1 A1 < sample.txt <--- 指定したコールバック関数を全行呼び出し(行末の改行を削除)
------- 読み込み配列[0] = aaa ------------ <--- 関数呼び出し時の引数は、配列要素のインデックスと要素に代入される値
------- 読み込み配列[1] = bbb ------------
------- 読み込み配列[2] = ccc ------------
------- 読み込み配列[3] = ddd ------------
------- 読み込み配列[4] = eee ------------
------- 読み込み配列[5] = fff ------------
$ mapfile -t -C samplefunc -c 2 A2 < sample.txt <--- 指定したコールバック関数を2行毎に呼び出し(行末の改行を削除)
------- 読み込み配列[1] = bbb ------------
------- 読み込み配列[3] = ddd ------------
------- 読み込み配列[5] = fff ------------
$ declare -p A1 <--- 行が読み込まれた配列「A1」
declare -a A1=([0]="aaa" [1]="bbb" [2]="ccc" [3]="ddd" [4]="eee" [5]="fff")
$ declare -p A2 <--- 行が読み込まれた配列「A2」
declare -a A2=([0]="aaa" [1]="bbb" [2]="ccc" [3]="ddd" [4]="eee" [5]="fff")
(34)
ディレクトリスタックからエントリを削除
実行結果
$ tree -d <--- ディレクトリ構成
.
├── workdir0
│ └── dir0
├── workdir1
└── workdir2
├── dir0
└── dir1
└── subdir0
7 directories
$ pwd
/home/testusr
$ pushd workdir0 <--- ディレクトリスタックに「~/workdir0」を追加して移動
~/workdir0 ~
$ pushd dir0 <--- ディレクトリスタックに「~/workdir0/dir0」を追加して移動
~/workdir0/dir0 ~/workdir0 ~
$ pushd ../../workdir2/dir0 <--- ディレクトリスタックに「~/workdir2/dir0」を追加して移動
~/workdir2/dir0 ~/workdir0/dir0 ~/workdir0 ~
$ pushd ../dir1/subdir0 <--- ディレクトリスタックに「~/workdir2/dir1/subdir0」を追加して移動
~/workdir2/dir1/subdir0 ~/workdir2/dir0 ~/workdir0/dir0 ~/workdir0 ~
$ pwd
/home/testusr/workdir2/dir1/subdir0
$ popd <--- ディレクトリスタックから「~/workdir2/dir1/subdir0」を削除
~/workdir2/dir0 ~/workdir0/dir0 ~/workdir0 ~
$ pwd
/home/testusr/workdir2/dir0 <--- 新たに先頭になった「~/workdir2/dir0」に移動
$ popd <--- ディレクトリスタックから「~/workdir2/dir0」を削除
~/workdir0/dir0
$ pwd
/home/testusr/workdir0/dir0 ~/workdir0 ~ <--- 新たに先頭になった「~/workdir0/dir0」に移動
$ popd <--- ディレクトリスタックから「~/workdir0/dir0」を削除
~/workdir0 ~
$ pwd
/home/testusr/workdir0 <--- 新たに先頭になった「~/workdir0」に移動
$ popd <--- ディレクトリスタックから「~/workdir0」を削除
~ <--- ディレクトリスタックが空となる
$ pwd
/home/testusr <--- ユーザーディレクトリへ戻る
実行結果
$ tree -d <--- ディレクトリ構成
.
├── workdir0
├── workdir1
└── workdir2
$ dirs <--- ディレクトリスタックの状況
~/workdir2 ~/workdir1 ~/workdir0 ~
$ pwd
/home/testusr/workdir2
$ popd <--- -nオプション無しで実行した結果(ここから)
~/workdir1 ~/workdir0 ~ <--- 先頭のディレクトリ「~/workdir2」が削除される
$ pwd
/home/testusr/workdir1
$ popd
~/workdir0 ~ <--- 先頭のディレクトリ「~/workdir1」が削除される
$ pwd
/home/testusr/workdir0 <--- -nオプション無しで実行した結果(ここまで)
$ popd
~
$ pwd
/home/testusr
︙
$ dirs
~/workdir2 ~/workdir1 ~/workdir0 ~
$ pwd
/home/testusr/workdir2
$ popd -n <--- -nオプションで実行
~/workdir2 ~/workdir0 ~ <--- 先頭のカレントディレクトリではなく「~/workdir1」を削除
$ pwd
/home/testusr/workdir2
$ popd -n <--- -nオプションで実行
~/workdir2 ~ <--- 先頭のカレントディレクトリではなく「~/workdir0」を削除
$ pwd
/home/testusr/workdir2
$ popd
~
$ pwd
/home/testusr
実行結果
$ tree -d <--- ディレクトリ構成
.
├── workdir0
├── workdir1
└── workdir2
$ dirs <--- ディレクトリスタックの状況
~/workdir2 ~/workdir1 ~/workdir0 ~
$ pwd
/home/testusr/workdir2
$ popd +2 <--- +2オプションで実行
~/workdir2 ~/workdir1 ~ <--- dirsのリストの左端(0)から数えて3番目の「~/workdir0」を削除
$ pwd
/home/testusr/workdir2 <--- ディレクトリは「~/workdir2」のまま
$ popd +0 <--- +0オプションで実行
~/workdir1 ~ <--- dirsのリストの左端(0)から数えて1番目の「~/workdir2」を削除
$ pwd
/home/testusr/workdir1 <--- ディレクトリは「~/workdir1」に移動
$ popd +0 <--- +0オプションで実行
~ <--- dirsのリストの左端(0)から数えて1番目の「~/workdir1」を削除
$ pwd
/home/testusr <--- ディレクトリは「~」に移動
︙
$ dirs <--- ディレクトリスタックの状況
~/workdir2 ~/workdir1 ~/workdir0 ~
$ pwd
/home/testusr/workdir2
$ popd -2 <--- -2オプションで実行
~/workdir2 ~/workdir0 ~ <--- dirsのリストの右端(0)から数えて3番目の「~/workdir1」を削除
$ pwd
/home/testusr/workdir2 <--- ディレクトリは「~/workdir2」のまま
$ popd -0 <--- -0オプションで実行
~/workdir2 ~/workdir0 <--- dirsのリストの右端(0)から数えて1番目の「~」を削除
$ pwd
/home/testusr/workdir2 <--- ディレクトリは「~/workdir2」のまま
$ popd -0 <--- -0オプションで実行
~/workdir2 <--- dirsのリストの右端(0)から数えて1番目の「~/workdir0」を削除
$ pwd
/home/testusr/workdir2 <--- ディレクトリは「~/workdir2」のまま
(35)
引数を指定したフォーマットで書き出す
実行結果
$ printf "%d %d\n" 123 -123 <--- %d : 符号付き10進数に変換
123 -123
$ printf "%i %i\n" 123 -123 <--- %i : 符号付き10進数に変換
123 -123
$ printf "%o %o %o\n" 123 -123 -1 <--- %o : 符号なし8進数に変換
173 1777777777777777777605 1777777777777777777777
$ printf "%u %u %u\n" 123 -123 -1 <--- %u : 符号なし10進数に変換
123 18446744073709551493 18446744073709551615
$ printf "%x %x\n" 123456 -123456 <--- %x : 符号なし16進数に変換
1e240 fffffffffffe1dc0
$ printf "%X %X\n" 123456 -123456 <--- %X : 符号なし16進数に変換
1E240 FFFFFFFFFFFE1DC0
$ printf "%e %e\n" 123456789 -123456789 <--- %e : 小数点数(指数表記)に変換
1.234568e+08 -1.234568e+08
$ printf "%E %E\n" 123456789 -123456789 <--- %E : 小数点数(指数表記)に変換
1.234568E+08 -1.234568E+08
$ printf "%f %f\n" 123.456789 -123.456789 <--- %f : 小数点数に変換
123.456789 -123.456789
$ printf "%F %F\n" 123.456789 -123.456789 <--- %F : 小数点数に変換
123.456789 -123.456789
$ printf "%.4g %.4g\n" 12345.6789 1234.6789 <--- %g : 小数点数に変換(指数表記の指数が精度以上の場合は%e)
1.235e+04 1235
$ printf "%g %g\n" 0.00012 0.000012 <--- %g : 小数点数に変換(指数表記の指数が-4未満の場合は%e)
0.00012 1.2e-05
$ printf "%.4G %.4G\n" 12345.6789 1234.6789 <--- %G : 小数点数に変換(指数表記の指数が精度以上の場合は%E)
1.235E+04 1235
$ printf "%G %G\n" 0.00012 0.000012 <--- %G : 小数点数に変換(指数表記の指数が精度以上の場合は%E)
0.00012 1.2E-05
$ printf "%c %c%c%c\n" $'\x30' $'\x41' $'\x42' $'\x43' <--- %c : unsigned charの「文字」に変換
0 ABC
$ printf "%s %s %s\n" abcdefg "hi jk" $PATH <--- %s : 文字列に変換
abcdefg hi jk /bin:/usr/bin
$ printf "abcde%nfg\n" sampvar ; echo $sampvar <--- 「%n」が出現するまでに出力された文字数を指定した変数に入力
abcdefg
5
$ printf "「%%」\n" <--- %% : 引数変換を行わず「%」を出力
「%」
$ printf "[%5d]\n" 30 <--- 最小フィールド幅5文字
[ 30]
$ printf "[%8d]\n" 30 <--- 最小フィールド幅8文字
[ 30]
$ printf "[%8s]\n" "abc" <--- 最小フィールド幅8文字
[ abc]
$ printf "[%-8s]\n" "abc" <--- 最小フィールド幅8文字 右詰め
[abc ]
$ printf "[%3s]\n" "abcdefg" <--- 最小フィールド幅3文字
[abcdefg]
$ printf "[%5d]\n" 123 <--- 最小フィールド幅5文字 精度無し
[ 123]
$ printf "[%5.5d]\n" 123 <--- 最小フィールド幅5文字 精度5桁
[00123]
$ printf "[%5.3d]\n" 12 <--- 最小フィールド幅5文字 精度3桁
[ 012]
$ printf "[%5.3d]\n" 1234 <--- 最小フィールド幅5文字 精度3桁
[ 1234]
$ printf "[%8f]\n" 1234.12 <--- 最小フィールド幅8文字 精度無し
[1234.120000]
$ printf "[%8.3f]\n" 1234.12 <--- 最小フィールド幅8文字 精度3桁
[1234.120]
$ printf "[%8.1f]\n" 1234.12 <--- 最小フィールド幅8文字 精度1桁
[ 1234.1]
$ printf "[%8.5g]\n" 123456789.123456 <--- 最小フィールド幅8文字 精度5桁 有効数字が5桁
[1.2346e+08]
$ printf "[%8.5e]\n" 123456789.123456 <--- 最小フィールド幅8文字 精度5桁 小数点以下が5桁
[1.23457e+08]
$ printf "[%8.5s]\n" "1234567890" <--- 最小フィールド幅8文字 精度5桁
[ 12345]
$ printf "%#o\n" 30 <--- フラグ「#」+ 「%o」 : 先頭に「0」を付加
036
$ printf "%#x\n" 30 <--- フラグ「#」+ 「%x」 : 先頭に「0x」を付加
0x1e
$ printf "%#X\n" 30 <--- フラグ「#」+ 「%X」 : 先頭に「0X」を付加
0X1E
$ printf "%05d\n" 30 <--- フラグ「0」 : 0(ゼロ)による左詰め
00030
$ printf "%05x\n" 30 <--- フラグ「0」 : 0(ゼロ)による左詰め
0001e
$ printf "[%-5d]\n" 30 <--- フラグ「-」 : 空白による右詰め
[30 ]
$ printf "[%-5x]\n" 30 <--- フラグ「-」 : 空白による右詰め
[1e ]
$ printf "[% d]\n" 30 <--- フラグ「 (空白)」 : 正の数値の場合数値の先頭に空白を付加
[ 30]
$ printf "[% d]\n" -30 <--- フラグ「 (空白)」 : 正の数値の場合数値の先頭に空白を付加
[-30]
$ printf "[% .3f]\n" 30.123 <--- フラグ「 (空白)」 : 正の数値の場合数値の先頭に空白を付加
[ 30.123]
$ printf "[% .3f]\n" -30.123 <--- フラグ「 (空白)」 : 正の数値の場合数値の先頭に空白を付加
[-30.123]
$ printf "[%+d]\n" 30 <--- フラグ「+」 : 数値の前に符号を付加
[+30]
$ printf "[%+d]\n" -30 <--- フラグ「+」 : 数値の前に符号を付加
[-30]
$ printf "[%+.3f]\n" 30.123 <--- フラグ「+」 : 数値の前に符号を付加
[+30.123]
$ printf "[%+.3f]\n" -30.123 <--- フラグ「+」 : 数値の前に符号を付加
[-30.123]
$ printf "%s\n" "ab\bcd" <--- 「%s」に対してバックスラッシュでエスケープされた文字を含む引数が与えられた場合
ab\bcd <--- 「\b」がそのまま「\b」として展開される
$ printf "%b\n" "ab\bcd" <--- 「%b」に対してバックスラッシュでエスケープされた文字を含む引数が与えられた場合
acd <--- 「\b」がバックスペースとして展開される
$ printf "%d %(%Y-%m-%d)T %(%H %M %S)T\n" $EPOCHSECONDS $EPOCHSECONDS $EPOCHSECONDS <--- %(日付フォーマット)T : 対応する引数(エポックからの秒数)をstrftime(3)のフォーマットを使用した日付文字列として出力
1672299801 2022-12-29 16 43 21 <--- シェル変数「EPOCHSECONDS」でエポックからの秒数を引数として利用
$ printf "%(%Y-%m-%d)T %(%H %M %S)T\n" -1 -1 <--- 引数「-1」は現在時刻を使用
2022-12-29 16 43 42
$ printf "%(%Y-%m-%d)T %(%H %M %S)T\n" -2 -2 <--- 引数「-2」はシェル起動時刻を使用
2022-12-29 14 01 54
実行結果
$ printf -v samplevar "%s %s %s\n" abcdefg "hi jk" $PATH <--- 出力先を変数「samplevar」指定
$ echo $samplevar <--- 変数の格納状況を確認
abcdefg hi jk /bin:/usr/bin
(36)
ディレクトリスタックへのディレクトリの追加やスタックのローテートなどを実行
実行結果
$ tree -d <--- ディレクトリ構成
.
├── workdir0
│ └── dir0
├── workdir1
└── workdir2
├── dir0
└── dir1
└── subdir0
7 directories
$ pwd
/home/testusr <--- 現在の作業ディレクトリ
$ pushd workdir0 <--- ディレクトリスタックに「~/workdir0」を追加して移動
~/workdir0 ~ <--- リストの左側に追加される
$ pwd
/home/testusr/workdir0
$ pushd dir0 <--- ディレクトリスタックに「~/workdir0/dir0」を追加して移動
~/workdir0/dir0 ~/workdir0 ~
$ pwd
/home/testusr/workdir0/dir0
$ pushd ../../workdir2/dir0 <--- ディレクトリスタックに「~/workdir2/dir0」を追加して移動
~/workdir2/dir0 ~/workdir0/dir0 ~/workdir0 ~
$ pwd
/home/testusr/workdir2/dir0
$ pushd ../dir1/subdir0 <--- ディレクトリスタックに「~/workdir2/dir1/subdir0」を追加して移動
~/workdir2/dir1/subdir0 ~/workdir2/dir0 ~/workdir0/dir0 ~/workdir0 ~
$ pwd
/home/testusr/workdir2/dir1/subdir0
実行結果
$ tree -d <--- ディレクトリ構成
.
├── workdir0
├── workdir1
└── workdir2
3 directories
$ dirs
~/workdir2 ~/workdir1 ~/workdir0 ~ <--- 現在のディレクトリスタック
$ pwd
/home/testusr/workdir2 <--- 現在の作業ディレクトリ
$ pushd +1 <--- 左端(0から始まる)から1番の位置がスタックの先頭になるようにローテート
~/workdir1 ~/workdir0 ~ ~/workdir2
$ pwd
/home/testusr/workdir1 <--- 作業ディレクトリも「~/workdir1」に移動
$ pushd +1 <--- 左端(0から始まる)から1番の位置がスタックの先頭になるようにローテート
~/workdir0 ~ ~/workdir2 ~/workdir1
$ pwd
/home/testusr/workdir0 <--- 作業ディレクトリが「~/workdir0」に移動
$ pushd -0 <--- 右端(0から始まる)から0番の位置がスタックの先頭になるようにローテート
~/workdir1 ~/workdir0 ~ ~/workdir2
$ pwd
/home/testusr/workdir1
$ pushd -0 <--- 右端(0から始まる)から0番の位置がスタックの先頭になるようにローテート
~/workdir2 ~/workdir1 ~/workdir0 ~
$ pwd
/home/testusr/workdir2
$ pushd -1 <--- 右端(0から始まる)から1番の位置がスタックの先頭になるようにローテート
~/workdir0 ~ ~/workdir2 ~/workdir1
$ pwd
/home/testusr/workdir0
$ pushd -2 <--- 右端(0から始まる)から2番の位置がスタックの先頭になるようにローテート
~ ~/workdir2 ~/workdir1 ~/workdir0
$ pwd
/home/testusr <--- 作業ディレクトリが「~」に移動
(37)
実行結果
$ pwd
/home/testusr <--- 現在のディレクトリの絶対パス
$ cd workdir0/ <--- ディレクトリを移動
$ pwd
/home/testusr/workdir0 <--- 現在のディレクトリの絶対パス
$ cd ../workdir1/ <--- ディレクトリを移動
$ pwd
/home/testusr/workdir1 <--- 現在のディレクトリの絶対パス
実行結果
$ ls -l symlinkdir
lrwxrwxrwx 1 testusr testusr 8 Jan 3 21:49 symlinkdir -> workdir0 <--- 「workdir0」へのシンボリックリンク
$ cd symlinkdir <--- 「symlinkdir」へ移動
$ pwd <--- オプション無しでpwdを実行
/home/testusr/symlinkdir <--- シンボリックリンクを含むパスを表示
$ pwd -P <--- -Pオプションでpwdを実行
/home/testusr/workdir0 <--- シンボリックリンクを含まないパスを表示
(38)
行の読み取りと単語分割
実行結果
$ read <--- 「read」のみで実行
aaa bbb ccc <--- 空白区切りで3つの単語を入力
$ echo $REPLY <--- 変数名の指定が無い場合は、読み取った行を変数$REPLYに格納
aaa bbb ccc
$ read W1 W2 W3 <--- 3つの変数名を指定して実行
aaa bbb ccc <--- 空白区切りで3つの単語を入力
$ echo "$W1 --- $W2 --- $W3"
aaa --- bbb --- ccc <--- 各々の変数に一つの単語を格納
$ read W1 W2 <--- 2つの変数名を指定して実行
aaa bbb ccc <--- 空白区切りで3つの単語を入力
$ echo "$W1 --- $W2"
aaa --- bbb ccc <--- 単語数が変数名より多い場合、最後の変数に残った単語と区切り文字が格納される
$ read W1 W2 W3 <--- 3つの変数名を指定して実行
aaa bbb <--- 空白区切りで2つの単語を入力
$ echo "$W1 --- $W2 --- $W3"
aaa --- bbb --- <--- 単語数が変数名より少ない場合、残った変数の値は空となる
$ read W1 W2 W3 <--- 3つの変数名を指定して実行
aaa \ <--- 「\」で行を連結して入力
> bbb \
> ccc
$ echo "$W1 --- $W2 --- $W3"
aaa --- bbb --- ccc
実行結果
$ read -a AAA <--- 配列変数「AAA」を指定して実行
aaa bbb ccc <--- 空白区切りで3つの単語を入力
$ echo $AAA
aaa
$ declare -p AAA
declare -a AAA=([0]="aaa" [1]="bbb" [2]="ccc") <--- 配列変数「AAA」の読み込み単語格納状況
実行結果
$ read -d '/' <--- 終了文字に「/」を指定して実行
aaa bbb ccc/$ echo $REPLY <--- 「/」を入力で終了(改行無し)
aaa bbb ccc
$ read -d '=' <--- 終了文字に「=」を指定して実行
aaa bbb ccc=$ echo $REPLY <--- 「=」を入力で終了(改行無し)
aaa bbb ccc
$ read -d '' <--- 終了文字にNULL文字を指定して実行
aaa bbb ccc^@$ echo $REPLY <--- NULL文字を入力で終了(改行無し)
aaa bbb ccc
実行結果
$ ls
sample1.txt sample2.txt sample3.txt
$ read -e
sam
$ ls
sample1.txt sample2.txt sample3.txt
$ read
sam
実行結果
$ read -e -i $( pwd ) -a AAA <--- readline使用を指定して-iオプションを使用
/home/testusr aaa bbb ccc <--- 入力行の初期値として展開された値の「/home/testusr」を配置
$ declare -p AAA
declare -a AAA=([0]="/home/testusr" [1]="aaa" [2]="bbb" [3]="ccc") <--- 読み込み内容
$ read -i $( pwd ) -a AAA <--- readline使用を指定せずに-iオプションを使用
aaa bbb ccc <--- 入力行の初期値としては何も配置されない
$ declare -p AAA
declare -a AAA=([0]="aaa" [1]="bbb" [2]="ccc")
実行結果
$ read -n 10 <--- 入力完了文字数に「10」を指定して実行
aaa bbb cc$ echo $REPLY <--- 空白を含めて10文字入力した時点で強制的に入力完了
aaa bbb cc
$ read -n 10 <--- 再度入力完了文字数に「10」を指定して実行
aa bb cc <--- 8文字入力後に改行を入力。指定文字数以下でも終了
$ echo $REPLY
aa bb cc
実行結果
$ read -N 10 <--- 入力完了文字数に「10」を指定して実行
aa bb cc d$ echo $REPLY <--- 空白を含めて10文字入力した時点で強制的に入力完了
aa bb cc d
$ read -N 10 <--- 再度入力完了文字数に「10」を指定して実行
aa bb <--- 区切り文字の「改行」が入力された場合も入力は継続される
cc d$ echo $REPLY <--- 「改行」を含まない入力文字数で終了
aa bb cc d <--- 読み取り結果にも「改行」は含まれない
サンプルファイル(sample.sh)
#!/bin/bash
read -p "読み込みデータ : " -a arydata
declare -p arydata
実行結果
$ ./sample.sh
読み込みデータ : aaa bbb ccc <--- 指定したプロンプトを表示
declare -a arydata=([0]="aaa" [1]="bbb" [2]="ccc")
実行結果
$ read
aaa bbb c\ <--- -rオプションがない場合、「\」は行の継続として機能
> ddd eee
$ echo $REPLY
aaa bbb cddd eee <--- 「\」は読み込まれない
$ read -r
aaa bbb c\ <--- -rオプション付きの場合、「\」は機能せずに改行で読み込み終了
$ echo $REPLY
aaa bbb c\ <--- 「\」も読み込まれる
実行結果
$ read -s <--- コマンド実行後、「aaa bbb ccc」を入力
$ echo $REPLY <--- 入力文字は表示されずに終了
aaa bbb ccc
サンプルファイル(sample.sh)
#!/bin/bash
echo "start $(date)"
while read -t 10 arydata
do
declare -p arydata
date
done
echo "end $(date)"
実行結果
$ ./sample.sh
start Sun 15 Jan 21:17:07 JST 2023
1 aa bb
declare -- arydata="1 aa bb"
Sun 15 Jan 21:17:10 JST 2023 <--- 10秒以内の入力
2 cc dd
declare -- arydata="2 cc dd"
Sun 15 Jan 21:17:14 JST 2023 <--- 10秒以内の入力
3 ee ff
declare -- arydata="3 ee ff"
Sun 15 Jan 21:17:19 JST 2023 <--- 10秒以内の入力
end Sun 15 Jan 21:17:29 JST 2023 <--- 未入力10秒経過でタイムアウト
実行結果
$ cat sample.txt <--- サンプル用ファイル
aaa bbb ccc
$ exec 3<sample.txt <--- fd 3 を「sample.txt」からのリダイレクトとして指定
$ read -u 3 <--- 標準入力の代わりに fd 3 を指定
$ exec 3<&- <--- fd 3 を閉じる
$ echo $REPLY
aaa bbb ccc
(39)
実行結果
$ samplevar=123 <--- サンプル用変数を生成
$ readonly samplevar <--- 読み込み専用属性の設定
$ readonly <--- 変数名の指定が無い場合は、読み取り専用変数リストの表示
declare -r BASHOPTS="checkwinsize:cmdhist:complete_fullquote:expand_aliases:...
declare -ar BASH_VERSINFO=([0]="5" [1]="1" [2]="16" [3]="1" [4]="release" [5]="x86_64-pc-linux-gnu")
︙
declare -r samplevar="123"
$ samplevar=234 <--- 読み取り専用変数への代入の試み
bash: samplevar: readonly variable <--- 代入不可
$ unset samplevar
bash: unset: samplevar: cannot unset: readonly variable <--- unsetも不可
$ exit <--- ログアウト
exit
$ su testusr <--- 再ログイン
Password:
$ samplevar=234 <--- 変数「samplevar」はリセット済
$ echo $samplevar <--- エラー無し
234
$ readonly samplevar2=345 <--- 変数名と値を指定
$ readonly
︙
declare -r samplevar2="345" <--- 読み取り専用変数に値が代入されている
実行結果
$ readonly -a sample1=(1 2 3) <--- 読み取り専用インデックス付き配列として生成
$ readonly -p -a <--- 読み取り専用インデックス付き配列のリストを出力
declare -ar BASH_VERSINFO=([0]="5" [1]="1" [2]="16" [3]="1" [4]="release" [5]="x86_64-pc-linux-gnu")
declare -ar sample1=([0]="1" [1]="2" [2]="3")
$ readonly -a <--- -pオプション未使用の場合も読み取り専用インデックス付き配列のリストを出力
declare -ar BASH_VERSINFO=([0]="5" [1]="1" [2]="16" [3]="1" [4]="release" [5]="x86_64-pc-linux-gnu")
declare -ar sample1=([0]="1" [1]="2" [2]="3")
$ readonly -a sample2=([key1]="value1" [key2]="value2") <--- 連想配列の生成時に-aオプションを使用
$ readonly -p -a
declare -ar BASH_VERSINFO=([0]="5" [1]="1" [2]="16" [3]="1" [4]="release" [5]="x86_64-pc-linux-gnu")
declare -ar sample1=([0]="1" [1]="2" [2]="3")
declare -ar sample2=([0]="value2") <--- 連想配列ではなくインデックス付き配列で生成
実行結果
$ readonly -A sample1=([key1]="value1" [key2]="value2") <--- 読み取り専用連想配列として生成
$ readonly -p -A <--- 読み取り専用連想配列のリストを出力
declare -Ar sample1=([key2]="value2" [key1]="value1" )
$ readonly -A <--- -pオプション未使用の場合も読み取り専用連想配列のリストを出力
declare -Ar sample1=([key2]="value2" [key1]="value1" )
$ readonly -A sample2=(1 2 3) <--- インデックス付き配列の生成時に-Aオプションを使用
$ readonly -p -A
declare -Ar sample1=([key2]="value2" [key1]="value1" )
declare -Ar sample2=([3]="" [1]="2" ) <--- インデックス付き配列ではなく連想配列で生成
実行結果
$ sampfunc1() { echo "sampfunc"; } <--- サンプル用関数を生成
$ readonly -f sampfunc1 <--- 関数を読み取り専用に指定
$ readonly -p -f <--- 読み取り専用関数のリストを表示
sampfunc1 ()
{
echo "sampfunc"
}
declare -fr sampfunc1
$ sampfunc1() { echo "reset"; } <--- 読み取り専用関数の上書きの試み
bash: sampfunc1: readonly function <--- 上書き不能
$ readonly -f samplevar=123 <--- 読み取り専用関数として変数を指定
bash: readonly: samplevar=123: not a function <--- 関数ではないためエラー発生
(40)
関数の実行を停止して指定した値を返す
サンプルファイル(sample.sh)
#!/bin/bash
samplefunc()
{
read -t 3 inputline
local n=$?
if (( n > 128 )); then
echo "タイムアウト"
return $n
fi
if [[ -z $inputline ]]; then
echo "入力長 0"
return 1
elif [[ $inputline == "0" ]]; then
echo "入力値 0"
return
else
echo "入力長 1以上"
return 2
fi
}
samplefunc
echo "samplefunc = $?"
実行結果
$ ./sample.sh
タイムアウト <--- 時間内に入力が行われずタイムアウト
samplefunc = 142 <--- returnによりreadコマンドから返された値を返す
$ ./sample.sh
<--- 空行を入力
入力長 0
samplefunc = 1 <--- return 1
$ ./sample.sh
0 <--- 0を入力
入力値 0
samplefunc = 0 <--- 引数無しのreturn
$ ./sample.sh
a <--- 上記以外の入力
入力長 1以上
samplefunc = 2 <--- return 1
(41)
実行結果
$ set
BASH=/bin/bash <--- シェル変数の名前と値
BASHOPTS=checkwinsize:cmdhist:complete_fullquote:expand_aliases:...
BASH_ALIASES=()
︙
実行結果
$ set -a <--- -aオプションを有効化
$ samplevar=123 <--- サンプル用シェル変数の生成
$ printenv | grep samplevar <--- 環境変数を確認
samplevar=123 <--- 「samplevar」の出力有り
$ set +a <--- -aオプションを無効化
$ unset samplevar <--- 「samplevar」を削除
$ samplevar=123 <--- 改めてサンプル用シェル変数を生成
$ printenv | grep samplevar
$ <--- 「samplevar」の出力無し
実行結果
$ sleep 10 & <--- サンプル用バックグラウンドジョブ(1)
[1] 548
$ sleep 5 & <--- サンプル用バックグラウンドジョブ(2)
[2] 549
$ echo 1 <--- 10秒経過後にコマンド実行
1
[1]- Done sleep 10 <--- 次のプロンプトの前にバックグラウンドジョブの終了通知を出力
[2]+ Done sleep 5
$ set -b <--- -bオプションを有効化
$ sleep 10 & <--- サンプル用バックグラウンドジョブ(1)
[1] 550
$ sleep 5 & <--- サンプル用バックグラウンドジョブ(2)
[2] 551
$ [2]+ Done sleep 5 <--- プロンプトでの入力の有無にかかわらず、バックグラウンドジョブ終了時に終了通知を出力
[1]- Done sleep 10
$ set +b <--- -bオプションを無効化
実行結果
$ ( set +e ; echo "サブシェル環境" ; ./a.out ; echo "終了ステータス : $?" ) <--- サブシェル環境内-eオプション無効でリストを実行
サブシェル環境
終了ステータス : 1 <--- 終了ステータスが0以外でも最終コマンドまで実行
$ ( set -e ; echo "サブシェル環境" ; ./a.out ; echo "終了ステータス : $?" ) <--- サブシェル環境内-eオプション有効でリストを実行
サブシェル環境 <--- 終了ステータスが0以外の場合は直ちに終了
実行結果
$ ls -l sample* <--- デフォルトではパス名展開が有効なため、特殊パターン文字「*」が任意の文字列にマッチ
-rw-rw-r-- 1 testusr testusr 12 Dec 21 23:11 sample1.txt
-rw-rw-r-- 1 testusr testusr 12 Dec 21 23:14 sample2.txt
-rw-rw-r-- 1 testusr testusr 13 Dec 21 23:14 sample3.txt
-rwxr-xr-x 1 testusr testusr 115 Jan 15 21:16 sample.sh
-rw-rw-r-- 1 testusr testusr 12 Jan 15 16:16 sample.txt
$ set -f <--- パス名展開を無効化
$ ls -l sample* <---
ls: cannot access 'sample*': No such file or directory <--- 特殊パターン文字「*」が認識されない
$ set +f <--- パス名展開を有効化
実行結果
$ hash -r <--- 記憶しているパス情報を削除
$ hash
hash: hash table empty <--- パス情報が空であることを確認
$ date <--- dateコマンドの実行(1回目)
Mon 23 Jan 08:36:12 JST 2023
$ hash <--- パス情報リストの表示
hits command
1 /bin/date <--- 実行したdateコマンドのパス情報
$ set +h <--- コマンドパス情報の記憶を無効化
$ date <--- dateコマンドの実行(2回目)
Mon 23 Jan 08:36:52 JST 2023
$ hash <--- パス情報リストの表示
bash: hash: hashing disabled <--- hash機能が無効であるためメッセージを出力
$ set -h <--- コマンドパス情報の記憶を有効化
$ date <--- dateコマンドの実行(3回目)
Mon 23 Jan 08:37:12 JST 2023
$ hash
hits command
2 /bin/date <--- 記憶が有効化されている状態で実行された2回分が記憶されている
サンプルファイル(sample.sh)
#!/bin/bash
sampfunc()
{
echo "引数 : $@"
echo "$a $b $c $d $e $f"
}
a=1
b=2
sampfunc c=3 d=4 # -kオプション無効
set -k
sampfunc e=5 f=6 # -kオプション有効
set +k
実行結果
$ ./sample.sh
引数 : c=3 d=4 <--- -kオプション無効の場合、引数「c=3」「d=4」として扱われる
1 2 <--- $c、$dの生成は無し
引数 : <--- -kオプション有効の場合、引数は無し
1 2 5 6 <--- $e、$fが生成される
サンプルファイル(sample.sh)
#!/bin/bash
echo "-nオプション無効"
set -n # -nオプションを有効化
echo "-nオプション有効化後" # 実行されない
実行結果
$ ./sample.sh
-nオプション無効 <--- 以降のコマンドは実行されない
実行結果
$ set -u <--- -uオプションを有効化
$ echo $abc
bash: abc: unbound variable <--- 未使用変数に対するメッセージ
$ set +u <--- -uオプションを無効化
$ echo $abc
<--- 未使用変数に対するメッセージ無し
実行結果
$ set -v <--- -vオプションを有効化
$ date
date <--- 読み込んだ入力行の表示
Thu 26 Jan 17:29:33 JST 2023
$ echo 123
echo 123 <--- 読み込んだ入力行の表示
123
$ echo $PATH
echo $PATH <--- 読み込んだ入力行の表示(展開はされない)
/bin:/usr/bin
$ set +v <--- -vオプションを無効化
set +v <--- 読み込んだ入力行の表示(以降は表示されない)
$ date
Thu 26 Jan 17:30:17 JST 2023
$ echo 123
123
$ echo $PATH
/bin:/usr/bin
実行結果
$ echo "($PS4)"
(+ ) <--- PS4の展開値
$ declare -a samplearray=(aa bb cc) <--- サンプル用配列変数
$ for a in ${samplearray[@]} ; do echo $a ; done <--- 複合コマンド「for」の実行
aa <--- -xオプション無効時はechoによる出力のみ
bb
cc
$ set -x <--- -xオプション有効化
$ echo 123 <--- 単純コマンドの実行
+ echo 123 <--- PS4値とechoコマンドを出力
123 <--- echoコマンド実行による出力
$ for a in ${samplearray[@]} ; do echo $a ; done <--- 複合コマンド「for」の実行
+ for a in ${samplearray[@]} <--- PS4値とforコマンド行を出力
+ echo aa <--- forコマンドの展開による展開された引数を伴うechoコマンドによる出力
aa <--- echoコマンド実行による出力
+ for a in ${samplearray[@]}
+ echo bb
bb
+ for a in ${samplearray[@]}
+ echo cc
cc
$ set +x <--- -xオプション無効化
+ set +x <--- PS4値とsetコマンド行を出力
実行結果
$ echo {犬,猫}が{走って,座って,寝て}いる <--- ブレース展開を含む引数
犬が走っている 犬が座っている 犬が寝ている 猫が走っている 猫が座っている 猫が寝ている <--- デフォルトでブレース展開は有効
$ set +B <--- ブレース展開を無効化
$ echo {犬,猫}が{走って,座って,寝て}いる
{犬,猫}が{走って,座って,寝て}いる <--- ブレース展開されずに文字列をそのまま出力
$ set -B <--- ブレース展開を有効化
$ echo {犬,猫}が{走って,座って,寝て}いる
犬が走っている 犬が座っている 犬が寝ている 猫が走っている 猫が座っている 猫が寝ている
実行結果
$ cat sample1.txt
既存ファイル sample1.txt <--- サンプル用ファイル1
$ echo "リダイレクト" > sample1.txt <--- -Cオプション無効時のリダイレクトの動作
$ cat sample1.txt
リダイレクト <--- 上書きされる
$ set -C <--- -Cオプションを有効化
$ cat sample2.txt
既存ファイル sample2.txt <--- サンプル用ファイル2
$ echo "リダイレクト" > sample2.txt
bash: sample2.txt: cannot overwrite existing file <--- 既存ファイルへの上書きエラー
$ echo "リダイレクト" >| sample2.txt <--- リダイレクト演算子「≥|」を使用して実行
$ cat sample2.txt
リダイレクト <--- エラー無しで上書きされる
実行結果
$ history <--- 現状の履歴リスト
1 ls -l
2 cat sample.txt
3 history
$ !2 <--- コマンド2を参照(実行)
cat sample.txt
サンプルファイル <--- 実行結果
$ set +H <--- !スタイルの履歴置換の無効化
$ history
1 ls -l
2 cat sample.txt
3 history
4 cat sample.txt
5 set +H
6 history
$ !2 <--- コマンド2を参照(実行)
bash: !2: command not found <--- 「!」が認識されない
$ set -H <--- !スタイルの履歴置換の無効化
$ !2
cat sample.txt
サンプルファイル
実行結果
$ ls -l symlinkdir
lrwxrwxrwx 1 testusr testusr 8 Feb 1 10:49 symlinkdir -> workdir0 <--- 「workdir0」へのシンボリックリンク
$ set -P <--- -Pオプションの有効化
$ cd symlinkdir <--- コマンドcdで作業ディレクトリをsymlinkdirへ変更
$ pwd
/home/testusr/workdir0 <--- 作業ディレクトリはシンボリックリンクを辿らずリンク先のディレクトリ
$ cd ..
$ set +P <--- -Pオプションの無効化
$ cd symlinkdir
$ pwd
/home/testusr/symlinkdir <--- 作業ディレクトリはシンボリックリンク
サンプルファイル(sample.sh)
#!/bin/bash
n=1
for a in $@
do
echo "\$$n $a"
n=$(( ++n ))
done
echo
set -- # 引数の無い--オプションで位置パラメータを削除
echo "位置パラメータを削除"
n=1
for a in $@
do
echo "\$$n $a"
n=$(( ++n ))
done
echo
set -- 4 5 6 # --オプションの引数を位置パラメータに設定
echo "--オプションの引数を位置パラメータに設定"
n=1
for a in $@
do
echo "\$$n $a"
n=$(( ++n ))
done
実行結果
$ ./sample.sh 1 2 3 <--- 3つの引数と共にサンプルスクリプトを実行
$1 1
$2 2
$3 3
位置パラメータを削除
<--- 位置パラメータ無し
--オプションの引数を位置パラメータに設定
$1 4 <--- 引数の値が位置パラメータに設定される
$2 5
$3 6
サンプルファイル(sample.sh)
#!/bin/bash
# 単独「-」以降の引数はオプションとして処理されずに位置パラメータに代入
set -B - -n -f
n=1
for a in $@
do
echo "\$$n $a"
n=$(( ++n ))
done
echo
# 単独「-」以降の引数が無い場合は位置パラメータの変更無し
set -B -
n=1
for a in $@
do
echo "\$$n $a"
n=$(( ++n ))
done
echo
実行結果
$ ./sample.sh
$1 -n <--- 「-」以降の引数が位置パラメータに代入される
$2 -f
$1 -n <--- 「-」以降の引数が無い場合は、位置パラメータに変更無し
$2 -f
主なオプション名(対応するコマンドオプション)
allexport (-a)
braceexpand (-B)
errexit (-e)
hashall (-h)
histexpand (-H)
keyword (-k)
noclobber (-C)
noexec (-n)
notify (-b)
nounset (-u)
physical (-P)
verbose (-v)
xtrace (-x)
braceexpand (-B)
errexit (-e)
hashall (-h)
histexpand (-H)
keyword (-k)
noclobber (-C)
noexec (-n)
notify (-b)
nounset (-u)
physical (-P)
verbose (-v)
xtrace (-x)
実行結果
$ set -o braceexpand <--- オプション「braceexpand」を有効化
$ echo {犬,猫}が{走って,座って,寝て}いる
犬が走っている 犬が座っている 犬が寝ている 猫が走っている 猫が座っている 猫が寝ている
$ set +o braceexpand <--- オプション「braceexpand」を無効化
$ echo {犬,猫}が{走って,座って,寝て}いる
{犬,猫}が{走って,座って,寝て}いる
(42)
指定した数値より上の位置パラメータを$1...と改名
サンプルファイル(sample.sh)
#!/bin/bash
set - 1 2 3 4 5
echo "shiftコマンドを実行しない場合"
echo "\$# = $#"
echo $@
echo
# 引数が$#以下
set - 1 2 3 4 5
shift 2
echo "shift 2"
echo $@
echo
# 引数が$#以上
set - 1 2 3 4 5
shift 6
echo "shift 6"
echo $@
echo
# 引数無し
set - 1 2 3 4 5
shift
echo "shift 引数無し"
echo $@
echo
# 引数 0
set - 1 2 3 4 5
shift 0
echo "shift 0"
echo $@
echo
実行結果
$ ./sample.sh
shiftコマンドを実行しない場合
$# = 5 <--- 位置パラメータ個数
1 2 3 4 5 <--- 5個の位置パラメータ
shift 2
3 4 5 <--- 位置2+1~のパラメータを$1~に改名
shift 6
1 2 3 4 5 <--- 指定した数値が$#以上の場合は変更なし
shift 引数無し
2 3 4 5 <--- 指定値=1
shift 0
1 2 3 4 5 <--- 変更なし
(43)
実行結果
$ shopt
autocd off <--- オプションの設定状態をon、offで出力
assoc_expand_once off
cdable_vars off
cdspell off
checkhash off
checkjobs off
checkwinsize on
cmdhist on
compat31 off
compat32 off
compat40 off
compat41 off
compat42 off
compat43 off
compat44 off
complete_fullquote on
direxpand off
dirspell off
dotglob off
execfail off
expand_aliases on
extdebug off
extglob off
extquote on
failglob off
force_fignore on
globasciiranges on
globstar off
gnu_errfmt off
histappend off
histreedit off
histverify off
hostcomplete on
huponexit off
inherit_errexit off
interactive_comments on
lastpipe off
lithist off
localvar_inherit off
localvar_unset off
login_shell off
mailwarn off
no_empty_cmd_completion off
nocaseglob off
nocasematch off
nullglob off
progcomp on
progcomp_alias off
promptvars on
restricted_shell off
shift_verbose off
sourcepath on
xpg_echo off
実行結果
$ shopt -p
shopt -u autocd <--- オプションの設定状態を再利用可能な形式で出力
shopt -u assoc_expand_once
shopt -u cdable_vars
shopt -u cdspell
shopt -u checkhash
shopt -u checkjobs
shopt -s checkwinsize
shopt -s cmdhist
shopt -u compat31
shopt -u compat32
shopt -u compat40
shopt -u compat41
shopt -u compat42
shopt -u compat43
shopt -u compat44
shopt -s complete_fullquote
shopt -u direxpand
shopt -u dirspell
shopt -u dotglob
shopt -u execfail
shopt -s expand_aliases
shopt -u extdebug
shopt -u extglob
shopt -s extquote
shopt -u failglob
shopt -s force_fignore
shopt -s globasciiranges
shopt -u globstar
shopt -u gnu_errfmt
shopt -u histappend
shopt -u histreedit
shopt -u histverify
shopt -s hostcomplete
shopt -u huponexit
shopt -u inherit_errexit
shopt -s interactive_comments
shopt -u lastpipe
shopt -u lithist
shopt -u localvar_inherit
shopt -u localvar_unset
shopt -u login_shell
shopt -u mailwarn
shopt -u no_empty_cmd_completion
shopt -u nocaseglob
shopt -u nocasematch
shopt -u nullglob
shopt -s progcomp
shopt -u progcomp_alias
shopt -s promptvars
shopt -u restricted_shell
shopt -u shift_verbose
shopt -s sourcepath
shopt -u xpg_echo
実行結果
$ shopt interactive_comments <--- 「interactive_comments」オプションの現状を確認
interactive_comments on
$ echo コメント#コメント
コメント#コメント <--- 単語の始め以外の「#」はコメント扱いとはならない
$ echo コメント #コメント
コメント <--- 単語の始めの「#」はコメントとなり、以降の文字は無視
$ shopt -u interactive_comments <--- 「interactive_comments」オプションを無効化
$ shopt interactive_comments
interactive_comments off
$ echo コメント #コメント
コメント #コメント <--- 単語の始めの「#」がコメントとして認識されない
$ shopt -s interactive_comments <--- 「interactive_comments」オプションを有効化
$ shopt interactive_comments
interactive_comments on
サンプルファイル(sample.sh)
#!/bin/bash
shopt xpg_echo
echo "line1\nline2" # バックスラッシュ・エスケープ・シーケンスを含む文字列
# 「xpg_echo」オプションを有効化
shopt -s xpg_echo
shopt xpg_echo
echo "line1\nline2" # バックスラッシュ・エスケープ・シーケンスを含む文字列
echo
echo "-qオプション有り"
if shopt -q xpg_echo; then
echo "xpg_echoはon"
else
echo "xpg_echoはoff"
fi
echo
echo "-qオプション無し"
if shopt xpg_echo; then
echo "xpg_echoはon"
else
echo "xpg_echoはoff"
fi
echo
# 「xpg_echo」オプションを無効化
shopt -u xpg_echo
shopt xpg_echo
echo
echo "-qオプション有り"
if shopt -q xpg_echo; then
echo "xpg_echoはon"
else
echo "xpg_echoはoff"
fi
echo
echo "-qオプション無し"
if shopt xpg_echo; then
echo "xpg_echoはon"
else
echo "xpg_echoはoff"
fi
echo
実行結果
$ ./sample.sh
xpg_echo off <--- デフォルトでは「xpg_echo」オプションは無効
line1\nline2
xpg_echo on <--- 「xpg_echo」オプションを有効化
line1 <--- バックスラッシュ・エスケープ・シーケンスが有効となり、「\n」で改行される
line2
-qオプション有り
xpg_echoはon <--- shoptコマンドからの出力は無し
-qオプション無し
xpg_echo on <--- shoptコマンドからの出力
xpg_echoはon
xpg_echo off <--- 「xpg_echo」オプションを無効化
-qオプション有り
xpg_echoはoff <--- shoptコマンドからの出力は無し
-qオプション無し
xpg_echo off <--- shoptコマンドからの出力
xpg_echoはoff
実行結果
$ shopt -o <--- 組み込みコマンドsetの-oオプションで定義されたオプションの現状を確認
allexport off
braceexpand on
emacs on
errexit off
errtrace off
functrace off
hashall on
histexpand on
history on
ignoreeof off
interactive-comments on
keyword off
monitor on
noclobber off
noexec off
noglob off
nolog off
notify off
nounset off
onecmd off
physical off
pipefail off
posix off
privileged off
verbose off
vi off
xtrace off
$ shopt -u braceexpand <--- -oオプション無しで、組み込みコマンドsetの-oオプションで定義されたオプションを設定変更
bash: shopt: braceexpand: invalid shell option name <--- 無効なシェルオプション名に対するエラー
$ shopt -o -u braceexpand <--- -oオプションで設定変更。エラー無し
$ shopt -o braceexpand <--- 現状の「braceexpand」の値を確認
braceexpand off
$ shopt -o -s braceexpand <--- 「braceexpand」を無効化
$ shopt -o braceexpand
braceexpand on
(44)
条件式の評価に応じて、0(true)または1(false)のステータスを返す
サンプルファイル(sample.sh)
#!/bin/bash
# 引数が0個
if test ; then
echo "引数が0個 : 式はtrue"
else
echo "引数が0個 : 式はfalse"
fi
# 引数が1個
if test "1" ; then
echo "引数が1個 : 式はtrue"
else
echo "引数が1個 : 式はfalse"
fi
# 引数が1個で値が空
if test "" ; then
echo "引数が1個 値は空 : 式はtrue"
else
echo "引数が1個 値は空 : 式はfalse"
fi
# 引数が2個で結果がtrueとなる単項演算子
if test -n "abc" ; then
echo "引数が2個で結果がtrue : 式はtrue"
else
echo "引数が2個で結果がtrue : 式はfalse"
fi
# 引数が「!」と空以外の値
if test ! "abc" ; then
echo "引数が「!」と空以外の値 : 式はtrue"
else
echo "引数が「!」と空以外の値 : 式はfalse"
fi
# 引数が「!」と空の値
if test ! "" ; then
echo "引数が「!」と空の値 : 式はtrue"
else
echo "引数が「!」と空の値 : 式はfalse"
fi
# 引数が3個
sampvar=1
if test "$sampvar" = "1" ; then
echo "引数が3個(評価結果はtrue) : 式はtrue"
else
echo "引数が3個(評価結果はtrue) : 式はfalse"
fi
# 引数が4個
if test ! "$sampvar" = "1" ; then
echo "引数が4個(評価結果はfalse) : 式はtrue"
else
echo "引数が4個(評価結果はfalse) : 式はfalse"
fi
実行結果
$ ./sample.sh
引数が0個 : 式はfalse <--- 引数0個は常にfalse
引数が1個 : 式はtrue
引数が1個 値は空 : 式はfalse <--- 引数1個で値が空の場合はfalse
引数が2個で結果がtrue : 式はtrue <--- 最初の引数が単項演算子の場合は式の評価結果を反映
引数が「!」と空以外の値 : 式はfalse <--- 演算子「!」は評価結果を反転
引数が「!」と空の値 : 式はtrue
引数が3個(評価結果はtrue) : 式はtrue <--- 二値条件演算子で引数1と引数3を評価
引数が4個(評価結果はfalse) : 式はfalse <--- 演算子「!」で上記評価結果を反転
(45)
シェル、およびシェルから実行されるプロセスの、累積ユーザ時間およびシステム時間を表示
サンプルファイル(sample.c)
#include <stdio.h>
int main()
{
long l;
for (l=0; l<1000000000; l++)
{
}
printf("end l=%ld\n", l);
return 0;
}
実行結果
$ times
0m0.030s 0m0.024s <--- シェルのユーザ時間とシステム時間(累積)
0m6.587s 0m0.279s <--- シェルから実行されたプロセスのユーザ時間とシステム時間(累積)
$ time ./a.out <--- コンパイルしたsample.cを実行
end l=1000000000
real 0m1.956s <--- コマンド実行に要した時間
user 0m1.954s <--- ユーザ時間
sys 0m0.001s <--- システム時間
$ times
0m0.031s 0m0.025s <--- 0.031 - 0.030 = 0.001s --- 0.025 - 0.024 = 0.001s
0m8.541s 0m0.280s <--- 8.541 - 6.587 = 1.954s --- 0.280 - 0.279 = 0.001s
(46)
実行結果
$ sampfunc() { echo sampfunc; } <--- サンプル用関数を定義
$ type sampfunc
sampfunc is a function <--- 指定した名前が関数であった場合の出力
sampfunc ()
{
echo sampfunc
}
$ alias spl='sampfunc' <--- サンプル用エイリアスを定義
$ type spl
spl is aliased to `sampfunc' <--- 指定した名前がエイリアスであった場合の出力
$ type type
type is a shell builtin <--- 指定した名前が組み込みシェルコマンドであった場合の出力
$ type while
while is a shell keyword <--- 指定した名前がシェル予約語であった場合の出力
$ type ls
ls is /bin/ls <--- 指定した名前が記憶される前のコマンドであった場合の出力
$ ls <--- コマンドlsを実行
a.out sample1.txt sample2.txt ...
$ type ls
ls is hashed (/bin/ls) <--- 指定した名前が記憶された後のコマンドであった場合の出力
実行結果
$ sampfunc() { echo sampfunc; }
$ type -t sampfunc
function <--- 指定した名前が関数であった場合は「function」
$ alias spl='sampfunc'
$ type -t spl
alias <--- 指定した名前がエイリアスであった場合は「alias」
$ type -t type
builtin <--- 指定した名前が組み込みシェルコマンドであった場合は「builtin」
$ type -t while
keyword <--- 指定した名前がシェル予約語であった場合は「keyword」
$ type -t ls
file <--- 指定した名前がディスク上のファイルであった場合は「file」
実行結果
$ type -a vi
vi is /usr/bin/vi <--- 初期状態として実行可能ファイル「vi」のみ存在
$ vi() { echo sampfunc; } <--- 関数「vi」を定義
$ alias vi='vi' <--- エイリアス「vi」を定義
$ type -a vi
vi is aliased to `vi' <--- エイリアス「vi」の表示
vi is a function <--- 関数「vi」の表示
vi ()
{
echo sampfunc
}
vi is /usr/bin/vi <--- 実行可能ファイル「vi」の表示
$ type vi
vi is aliased to `vi' <--- オプション無しの場合はエイリアスのみを表示
$ unset vi <--- 関数「vi」を削除
$ type -a vi
vi is aliased to `vi'
vi is /usr/bin/vi
$ unalias vi <--- エイリアス「vi」を削除
$ type -a vi
vi is /usr/bin/vi
実行結果
$ sampfunc() { echo sampfunc; } <--- サンプル用関数を定義
$ alias spl='sampfunc' <--- サンプル用エイリアスを定義
$ type sampfunc
sampfunc is a function <--- オプション無しの場合は指定した関数を表示
sampfunc ()
{
echo sampfunc
}
$ type -f sampfunc <--- オプション無しの場合は指定した関数を表示
bash: type: sampfunc: not found <--- -fオプションを使用すると関数は対象外となる
$ type -f spl
spl is aliased to `sampfunc' <--- エイリアスは表示対象
(47)
実行結果
(青色はリミット設定オプション)
(青色はリミット設定オプション)
$ ulimit -a
real-time non-blocking time (microseconds, -R) unlimited
core file size (blocks, -c) unlimited <--- 作成されるコアファイルの最大サイズ
data seg size (kbytes, -d) unlimited <--- プロセスのデータセグメントの最大サイズ
scheduling priority (-e) 0 <--- スケジューリング優先度("nice")の最大値
file size (blocks, -f) unlimited <--- シェルとその子プロセスが書き込むファイルの最大サイズ
pending signals (-i) 3900 <--- 保留中シグナルの最大数
max locked memory (kbytes, -l) 16384 <--- メモリにロック可能な最大サイズ
max memory size (kbytes, -m) unlimited <--- 最大常駐セットサイズ
open files (-n) 1024 <--- ファイルディスクリプタの最大オープン数
pipe size (512 bytes, -p) 8 <--- 512 バイトブロック単位のパイプサイズ
POSIX message queues (bytes, -q) 819200 <--- POSIXメッセージキューの最大バイト数
real-time priority (-r) 0 <--- リアルタイムスケジューリング優先順位の最大値
stack size (kbytes, -s) 8192 <--- 最大スタックサイズ
cpu time (seconds, -t) unlimited <--- CPU時間の最大値
max user processes (-u) 3900 <--- 1人のユーザーが利用できる最大プロセス数
virtual memory (kbytes, -v) unlimited <--- CPU時間の最大値
file locks (-x) unlimited <--- ファイルロックの最大数
実行結果
$ ulimit -H -a <--- 表示するリソースのリミットをハードリミットに指定
real-time non-blocking time (microseconds, -R) unlimited
core file size (blocks, -c) unlimited
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 3900
max locked memory (kbytes, -l) 16384
max memory size (kbytes, -m) unlimited
open files (-n) 4096
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) unlimited
cpu time (seconds, -t) unlimited
max user processes (-u) 3900
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
$ ulimit -S -a <--- 表示するリソースのリミットをソフトリミットに指定
real-time non-blocking time (microseconds, -R) unlimited
core file size (blocks, -c) unlimited
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 3900
max locked memory (kbytes, -l) 16384
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 3900
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
(48)
サンプルファイル(sample.sh)
#!/bin/bash
maskvar=$(umask)
echo "現在のマスク"
umask
echo
echo "変更前のマスクにより「samp_file1」を作成"
touch samp_file1
echo "変更前のマスクにより「samp_dir1」を作成"
mkdir -v samp_dir1
echo
echo "0022に変更"
umask 0022
umask
echo
echo "「0022」へ変更後のマスクにより「samp_file2」を作成"
touch samp_file2
echo "「0022」へ変更後のマスクにより「samp_dir2」を作成"
mkdir -v samp_dir2
echo
echo "0000に変更"
umask 0000
umask
echo
echo "「0000」変更後のマスクにより「samp_file3」を作成"
touch samp_file3
echo "「0000」へ変更後のマスクにより「samp_dir3」を作成"
mkdir -v samp_dir3
echo
echo "元に戻す"
umask ${maskvar}
umask
実行結果
$ ./sample.sh
現在のマスク
0002
変更前のマスクにより「samp_file1」を作成
変更前のマスクにより「samp_dir1」を作成
mkdir: created directory 'samp_dir1'
0022に変更
0022
「0022」へ変更後のマスクにより「samp_file2」を作成
「0022」へ変更後のマスクにより「samp_dir2」を作成
mkdir: created directory 'samp_dir2'
0000に変更
0000
「0000」変更後のマスクにより「samp_file3」を作成
「0000」へ変更後のマスクにより「samp_dir3」を作成
mkdir: created directory 'samp_dir3'
元に戻す
0002
$ ls -l
total 16
drwxrwxr-x 2 testusr testusr 4096 Feb 19 16:17 samp_dir1 <--- 0002(000 000 010) 設定されているビットにはパーミッションは付与されない
drwxr-xr-x 2 testusr testusr 4096 Feb 19 16:17 samp_dir2 <--- 0022(000 010 010)
drwxrwxrwx 2 testusr testusr 4096 Feb 19 16:17 samp_dir3 <--- 0000(000 000 000)
-rw-rw-r-- 1 testusr testusr 0 Feb 19 16:17 samp_file1 <--- 0002(000 000 010)
-rw-r--r-- 1 testusr testusr 0 Feb 19 16:17 samp_file2 <--- 0022(000 010 010)
-rw-rw-rw- 1 testusr testusr 0 Feb 19 16:17 samp_file3 <--- 0000(000 000 000)
-rwxr-xr-x 1 testusr testusr 773 Feb 19 16:17 sample.sh
実行結果
$ umask -S <--- -Sオプションで記号による現在のマスクを表示
u=rwx,g=rwx,o=rx <--- 記号による表現
$ umask
0002 <--- 数値による表現
$ umask -S u=rwx,g=rx,o=rx <--- -Sオプションでマスクを記号により設定「0022」
u=rwx,g=rx,o=rx
$ umask
0022 <--- 数値による表現
$ umask -S u=rwx,g=rwx,o=rwx <--- -Sオプションでマスクを記号により設定「0000」
u=rwx,g=rwx,o=rwx
$ umask
0000 <--- 数値による表現
$ umask -S u=rwx,g=rwx,o=rx <--- -Sオプションでマスクを記号により設定「0002」(元に戻す)
u=rwx,g=rwx,o=rx
$ umask
0002 <--- 数値による表現
実行結果
$ umask
0002 <--- -pオプション無しの数値表現の場合の出力
$ umask -p
umask 0002 <--- 再利用可能形式での出力
$ umask -S
u=rwx,g=rwx,o=rx <--- -pオプション無しの記号表現の場合の出力
$ umask -S -p
umask -S u=rwx,g=rwx,o=rx <--- 再利用可能形式での出力
(49)
実行結果
$ alias <--- 現状エイリアスが存在しないことを確認
$ alias sample_alias1='echo echo_sample1' <--- サンプル用エイリアスを定義
$ alias sample_alias2='echo echo_sample2' <--- 〃
$ alias sample_alias3='echo echo_sample3' <--- 〃
$ alias <--- サンプル用エイリアスが定義済であることを確認
alias sample_alias1='echo echo_sample1'
alias sample_alias2='echo echo_sample2'
alias sample_alias3='echo echo_sample3'
$ unalias sample_alias1 <--- サンプル用エイリアス1を削除
$ alias
alias sample_alias2='echo echo_sample2'
alias sample_alias3='echo echo_sample3'
$ unalias sample_alias3 <--- サンプル用エイリアス3を削除
$ alias
alias sample_alias2='echo echo_sample2'
$ unalias sample_alias2 <--- サンプル用エイリアス2を削除
$ alias <--- すべてのエイリアスが削除済
実行結果
$ alias <--- 現状エイリアスが存在しないことを確認
$ alias sample_alias1='echo echo_sample1' <--- サンプル用エイリアスを定義
$ alias sample_alias2='echo echo_sample2' <--- 〃
$ alias sample_alias3='echo echo_sample3' <--- 〃
$ alias <--- サンプル用エイリアスが定義済であることを確認
alias sample_alias1='echo echo_sample1'
alias sample_alias2='echo echo_sample2'
alias sample_alias3='echo echo_sample3'
$ unalias -a <--- 全エイリアスを削除
$ alias
$ <--- すべてのエイリアスが削除済
(50)
実行結果
$ sample1="aaa" <--- サンプル用変数を定義
$ declare -p sample1 <--- sample1が定義済であることを確認
declare -- sample1="aaa"
$ unset sample1 <--- sample1を削除
$ declare -p sample1
bash: declare: sample1: not found <--- sample1が見つからない
$ function sample1 { echo aaa; } <--- サンプル用関数を定義
$ declare -f sample1
sample1 ()
{
echo aaa
}
$ unset sample1 <--- sample1を削除
$ declare -f sample1 <--- 関数が削除され、表示されない
$ sample1="aaa"
$ readonly sample1 <--- 読み込み専用属性を設定
$ unset sample1 <--- sample1を削除
bash: unset: sample1: cannot unset: readonly variable <--- 読み込み専用変数は削除不能
$
実行結果
$ sample1="aaa" <--- サンプル用変数を定義
$ declare -p sample1 <--- sample1が定義済であることを確認
declare -- sample1="aaa"
$ unset -v sample1 <--- 「-v」オプションでsample1を削除
$ declare -p sample1
bash: declare: sample1: not found <--- sample1は削除済で見つからない
$ function sample1 { echo aaa; } <--- サンプル用関数を定義
$ declare -f sample1 <--- sample1が定義済であることを確認
sample1 ()
{
echo aaa
}
$ unset -v sample1 <--- 「-v」オプションでsample1を削除
$ declare -f sample1
sample1 () <--- 関数sample1は削除されない
{
echo aaa
}
実行結果
$ function sample1 { echo aaa; } <--- サンプル用関数を定義
$ declare -f sample1 <--- sample1が定義済であることを確認
sample1 ()
{
echo aaa
}
$ unset -f sample1 <--- 「-f」オプションでsample1を削除
$ declare -f sample1 <--- sample1は削除済で見つからない
$ sample1="aaa" <--- サンプル用変数を定義
$ declare -p sample1 <--- sample1が定義済であることを確認
declare -- sample1="aaa"
$ unset -f sample1 <--- 「-f」オプションでsample1を削除
$ declare -p sample1
declare -- sample1="aaa" <--- 変数sample1は削除されない
実行結果
$ declare -a sample1=("aa" "bb" "cc") <--- サンプル用配列を定義
$ declare -n sample2=sample1[2] <--- サンプル用に名前参照属性を付与して配列の要素を参照する変数を定義
$ echo "sample2 = $sample2"
sample2 = cc <--- sample2はsample1[2]を返す
$ declare -p sample2 <--- sample2の定義情報を確認
declare -n sample2="sample1[2]"
$ unset sample2 <--- -nオプション無しでsample2に対しunset実行
$ declare -p sample2
declare -n sample2="sample1[2]" <--- sample2自体には変化なし
$ declare -p sample1
declare -a sample1=([0]="aa" [1]="bb") <--- 参照対象だった要素[2]が削除されている
$ unset -n sample2 <--- -nオプションを付けてsample2に対しunset実行
$ declare -p sample2
bash: declare: sample2: not found <--- sample2が削除されている
実行環境
GNU bash, version 5.1.16
GCC-8.2.0
GNU C Library 2.28
GNU Binutils 2.31.1
GCC-8.2.0
GNU C Library 2.28
GNU Binutils 2.31.1
コード例・出力内容中の表記
・実行例中の太字表記部分は、コマンドなどの入力された文字列を示します。
・「︙」や「...」の着色省略表記は、 実際のソースコードや出力内容などを省略加工した部分を示します。
・「︙」や「...」の着色省略表記は、 実際のソースコードや出力内容などを省略加工した部分を示します。