Last Update 2022/06/28
シェル文法
テスト項目
(01) 単純コマンド
(02) パイプライン
(03) リスト(list)
(04)
(
リスト
)
(05)
{
リスト
; }
(06)
((
式
))
(07)
[[
式
]]
(08)
for
(09)
select
(10)
case
(12)
while
(13)
until
(14) シェル関数
c_sample1.c(実行ファイル c_sample1)
#include <stdio.h>
int main(int argc, char *argv[])
{
int i;
for (i=0; i<argc; i++)
{
printf("引数 %d -- %s\n", i, argv[i]);
}
return 100;
}
実行結果(1)
$ ./c_sample1 arg1 arg2
引数 0 -- ./c_sample1 <--- 0番目の引数は最初の単語となる実行コマンド
引数 1 -- arg1 <--- 以降、引数として空白で区切られた単語
引数 2 -- arg2 <---
$
実行結果(2)
リダイレクトを含む場合
リダイレクトを含む場合
$ ./c_sample1 arg1 arg2 > c_sample1.txt
$ cat c_sample1.txt
引数 0 -- ./c_sample1
引数 1 -- arg1
引数 2 -- arg2
$
実行結果(3)
終了ステータスに関するテスト
終了ステータスに関するテスト
$ ./c_sample1 arg1 arg2
引数 0 -- ./c_sample1
引数 1 -- arg1
引数 2 -- arg2
$ echo $?
100 <--- サンプルコマンドの終了ステータス(コードで指定された戻り値)
$ sleep 10 <--- sleepコマンドの実行
$ echo $?
0 <--- sleepコマンド正常終了時の終了ステータス
$ sleep 10
^C <--- 実行中のsleepコマンドをCtrl-cで中断
$ echo $?
130 <--- シグナル(SIGINT (数値で2))で終了のため 2 + 128 = 130
c_sample2_1.c(実行ファイル c_sample2_1)
#include <stdio.h>
int main()
{
/* 標準出力へ出力 */
printf("c_sample2\n");
/* 標準エラーへ出力 */
fprintf(stderr, "stderr c_sample2\n");
return 0;
}
c_sample2_2.c(実行ファイル c_sample2_2)
#include <stdio.h>
int main()
{
char s[100];
/* 標準入力から読み込み */
while (fgets(s, 100, stdin) != NULL)
{
/* 読み込んだ文字列を標準出力へ出力 */
printf("stdin : %s", s);
}
printf("\n");
return 0;
}
実行結果(1)
制御演算子「|」でc_sample2_1の標準出力からc_sample2_2の標準入力に接続
制御演算子「|」でc_sample2_1の標準出力からc_sample2_2の標準入力に接続
$ ./c_sample2_1 | ./c_sample2_2
stderr c_sample2 <--- 標準エラーは標準入力へ接続されない
stdin : c_sample2
$
実行結果(2)
制御演算子「|&」でc_sample2_1の標準出力からc_sample2_2の標準入力に接続
制御演算子「|&」でc_sample2_1の標準出力からc_sample2_2の標準入力に接続
$ ./c_sample2_1 |& ./c_sample2_2
stdin : stderr c_sample2 <--- 標準エラーも標準入力へ接続される
stdin : c_sample2
$
実行結果(3)
「time」による経過時間情報の出力
「time」による経過時間情報の出力
$ time ./c_sample2_1 <--- 1つのコマンドに「time」を付けて実行
c_sample2
stderr c_sample2
real 0m0.001s <--- コマンドの経過時間情報を出力
user 0m0.000s
sys 0m0.001s
$ time ./c_sample2_1 | ./c_sample2_2 <--- パイプラインに「time」を付けて実行
stderr c_sample2
stdin : c_sample2
real 0m0.002s <--- パイプライン全体の経過時間情報を出力
user 0m0.001s
sys 0m0.001s
$ time ./c_sample2_1 | ./c_sample2_2 ; ./c_sample2_1 <--- パイプラインに「;」でコマンドを追加
stderr c_sample2
stdin : c_sample2
real 0m0.002s
user 0m0.000s
sys 0m0.001s
c_sample2 <--- パイプラインの経過時間情報を出力後にコマンドを実行
stderr c_sample2
c_sample3_1.c(実行ファイル c_sample3_1)
#include <stdio.h>
int main()
{
/* 標準出力へ出力 */
printf("c_sample3_1\n");
return 0;
}
c_sample3_2.c(実行ファイル c_sample3_2)
#include <stdio.h>
int main()
{
char s[100];
/* 標準入力から読み込み */
fgets(s, 100, stdin);
/* 読み込んだ文字列を標準出力へ出力 */
printf("stdin : %s", s);
return 0;
}
c_sample3_3.c(実行ファイル c_sample3_3)
#include <stdio.h>
int main()
{
/* 終了ステータス 1 */
return 1;
}
sample3.sh
#!/bin/bash
# 以下の部分全体がリスト(list)
# パイプラインとコマンドの区切りに「;」を使用
# パイプライン ; コマンド ; コマンド
./c_sample3_1 | ./c_sample3_2 ; echo "start" ; echo "end"
echo
# 改行もコマンド区切りとして機能
# 下記コマンド実行で最終終了ステータスに1をセット
./c_sample3_3
echo "現在の最終終了ステータス : $?"
# コマンドが制御演算子「&」で終わっている場合はバックグラウンドで実行
echo "バックグラウンドでコマンドを実行"
sleep 1 &
# バックグラウンドでコマンド実行の際は、コマンド終了を待たずに終了ステータス0が戻される
echo "バックグラウンドで実行直後の最終終了ステータス : $?"
# 現在稼働中のプロセスを表示
ps
echo
echo "ANDリスト"
# 「&&」で区切られたリスト
# 左側のパイプライン(コマンド)の終了ステータスが「0」の場合に右側を実行
./c_sample3_1 | ./c_sample3_2 && echo "ANDリスト終了"
echo
echo "ORリスト"
# 「||」で区切られたリスト
# 左側のパイプライン(コマンド)の終了ステータスが「0」以外の場合に右側を実行
./c_sample3_3 || echo "ORリスト終了"
echo
echo "sleep 1 実行"
sleep 1
echo
# 再度現在稼働中のプロセスを表示
ps
実行結果
$ ./sample3.sh
stdin : c_sample3_1 <--- パイプラインを含む「;」区切りのリストを実行
start
end
現在の最終終了ステータス : 1
バックグラウンドでコマンドを実行
バックグラウンドで実行直後の最終終了ステータス : 0 <--- バックグラウンドでコマンド実行直後の終了ステータス
PID TTY TIME CMD
255 pts/0 00:00:00 bash
295 pts/0 00:00:00 sample3.sh
299 pts/0 00:00:00 sleep <--- バックグラウンドで実行中
300 pts/0 00:00:00 ps
ANDリスト
stdin : c_sample3_1
ANDリスト終了 <--- ANDリストを終端まで実行
ORリスト
ORリスト終了 <--- ORリストを終端まで実行
sleep 1 実行 <--- sleepコマンド実行後稼働中プロセスの確認
PID TTY TIME CMD
255 pts/0 00:00:00 bash
295 pts/0 00:00:00 sample3.sh
305 pts/0 00:00:00 ps
$
sample4.sh
#!/bin/bash
n=1
echo "n = $n"
echo
# 「;」で区切られたリスト
(echo "(リスト)[1]ここから" ; i=2 ; echo "n = $n" ; echo "i = $i" ; echo "(リスト)[1]ここまで")
echo
# 改行で区切られたリスト
(
echo "(リスト)[2]ここから"
echo "n = $n"
n=3
echo "n = $n"
echo "(リスト)[2]ここまで"
)
echo
echo "n = $n"
echo "i = $i"
実行結果
$ ./sample4.sh
n = 1 <--- サブシェル外で変数に値を代入
(リスト)[1]ここから
n = 1 <--- サブシェル外で代入された変数値は有効
i = 2
(リスト)[1]ここまで
(リスト)[2]ここから
n = 1
n = 3
(リスト)[2]ここまで
n = 1 <--- サブシェル内で代入された変数値はサブシェル外では無効
i = <--- 〃
$
sample5.sh
#!/bin/bash
n=1
echo "n = $n"
echo
# 「;」で区切られたリスト
# 「{」とリスト間の空白文字とリストと「}」間の「;」など、単語分割のための適切なメタ文字は必須
{ echo "(リスト)[1]ここから" ; i=2 ; echo "n = $n" ; echo "i = $i" ; echo "(リスト)[1]ここまで" ; }
echo
# 改行で区切られたリスト
{
echo "(リスト)[2]ここから"
echo "n = $n"
n=3
echo "n = $n"
echo "(リスト)[2]ここまで"
}
echo
echo "n = $n"
echo "i = $i"
実行結果
$ ./sample5.sh
n = 1 <--- 「{ }」外で変数に値を代入
(リスト)[1]ここから
n = 1 <--- 「{ }」外で代入された変数値は有効
i = 2
(リスト)[1]ここまで
(リスト)[2]ここから
n = 1
n = 3
(リスト)[2]ここまで
n = 3 <--- 「{ }」内で代入された変数値も有効
i = 2 <--- 〃
$
sample6.sh
#!/bin/bash
# AND・ORリストによる (( 式 )) の動作テスト
# cmd1 && cmd2 : cmd1が0を返した場合にcmd2を実行
# cmd1 || cmd2 : cmd1が0以外を返した場合にcmd2を実行
# (( 式 )) : 「式の値」が0ではない場合、ステータス0を返す
# $(( 式 )) : 「式」の算術式評価による式の値(算術式展開)
# パラメータ展開・文字列展開・コマンド置換・クォートの削除を実行
echo "引数個数 : $#"
echo
echo "等価演算子による算術式評価"
echo "算術式展開 \$((\$# == 2)) : $(($# == 2))" ; (($# == 2)) && echo "((\$# == 2)) : 0を返す"
echo "算術式展開 \$((\$# != 2)) : $(($# != 2))" ; (($# != 2)) || echo "((\$# != 2)) : 1を返す"
echo
echo "代入演算子による算術式評価"
echo "算術式展開 \$((n1 = 3)) : $((n1 = 3))" ; ((n1 = 3)) && echo "((n1 = 3)) : 0を返す"
echo
echo "インクリメント演算子による算術式評価"
echo "算術式展開 \$((n2 = 3)) : $((n2 = 3))"
echo "算術式展開 \$((n2++)) : $((n2++))"
((n2 = 3)) && ((n2++)) && echo "((n2 = 3)) : 0を返す --- ((n2++)) : 0を返す"
echo "n2 = $n2"
echo
# 変数bbbに1を代入
bbb=1
echo "文字列と数値0による式の評価"
echo "算術式展開 \$((\"aaa\" == 0)) : $(("aaa" == 0))" ; (("aaa" == 0)) && echo "((\"aaa\" == 0)) : 0を返す"
echo "算術式展開 \$((\"bbb\" == 0)) : $(("bbb" == 0))" ; (("bbb" == 0)) || echo "((\"bbb\" == 0)) : 1を返す"
echo "算術式展開 \$((\"bbb\" == 1)) : $(("bbb" == 1))" ; (("bbb" == 1)) && echo "((\"bbb\" == 1)) : 0を返す"
echo
実行結果
$ ./sample6.sh a b
引数個数 : 2
等価演算子による算術式評価
算術式展開 $(($# == 2)) : 1 <--- 算術式展開による算術式の評価結果(式の値)
(($# == 2)) : 0を返す <--- 「式の値」が0ではないためステータス0を返す
算術式展開 $(($# != 2)) : 0
(($# != 2)) : 1を返す <--- 「式の値」が0のためステータス1を返す
代入演算子による算術式評価
算術式展開 $((n1 = 3)) : 3
((n1 = 3)) : 0を返す <--- 「式の値」が0ではないためステータス0を返す
インクリメント演算子による算術式評価
算術式展開 $((n2 = 3)) : 3
算術式展開 $((n2++)) : 3 <--- パラメータ展開が評価前のため「式の値」は3
((n2 = 3)) : 0を返す --- ((n2++)) : 0を返す <--- 2つの「式の値」が0ではないためステータス0を返す
n2 = 4 <--- 変数の値は評価時の演算結果を反映
文字列と数値0による式の評価 (注)この項目の下記コメントは、出力結果などからの推測によるもの
算術式展開 $(("aaa" == 0)) : 1 <--- 変数名参照による展開とクォートの削除により「0 == 0」
(("aaa" == 0)) : 0を返す
算術式展開 $(("bbb" == 0)) : 0 <--- 変数名参照による展開とクォートの削除により「1 == 0」
(("bbb" == 0)) : 1を返す
算術式展開 $(("bbb" == 1)) : 1 <--- 変数名参照による展開とクォートの削除により「1 == 1」
(("bbb" == 1)) : 0を返す
sample7.sh
#!/bin/bash
# AND・ORリストによる [[ 式 ]] の動作テスト
# cmd1 && cmd2 : cmd1が0を返した場合にcmd2を実行
# cmd1 || cmd2 : cmd1が0以外を返した場合にcmd2を実行
# [[ 式 ]] : 式の評価値によって0または1を返す
# チルダ展開・パラメータと変数の展開・算術式展開・コマンド置換・プロセス置換・クォート除去を実行
n=123
s="abc"
echo "n = $n"
echo "s = $s"
echo
echo "算術比較の実行"
[[ $n -eq 123 ]] && echo "[[ \$n -eq 123 ]] : 0を返す"
[[ $n -ne 123 ]] || echo "[[ \$n -ne 123 ]] : 1を返す"
echo
echo "文字列比較の実行"
[[ $s == "abc" ]] && echo "[[ \$s == \"abc\" ]] : 0を返す"
[[ $s != "abc" ]] || echo "[[ \$s != \"abc\" ]] : 1を返す"
echo
echo "ファイルの存在確認の実行"
echo "\$0 = $0"
[[ -f "$0" ]] && echo "[[ -f \"\$0\" ]] : 0を返す"
[[ -f "$0.txt" ]] || echo "[[ -f \"\$0.txt\" ]] : 1を返す"
echo
str="123 abc"
echo "パターンマッチング"
[[ $0 == *.sh ]] && echo "[[ \$0 == *.sh ]] : 0を返す"
[[ $0 == *[.,@]sh ]] && echo "[[ \$0 == *[.,@]sh ]] : 0を返す"
[[ $str == 123[[:blank:]]abc ]] && echo "[[ \$str == 123[[:blank:]]abc ]] : 0を返す"
[[ $str != 23[[:blank:]]abc ]] && echo "[[ \$str != 23[[:blank:]]abc ]] : 0を返す"
echo
echo "正規表現によるパターンマッチング"
[[ $0 =~ ^.+\.sh$ ]] && echo "[[ \$0 =~ ^.+\.sh\$ ]] : 0を返す"
[[ $0 =~ *[.,@]sh ]] || echo "[[ \$0 == *[.,@]sh ]] : 0以外を返す"
[[ $str =~ "23 abc" ]] && echo "[[ \$str =~ \"23 abc\" ]] : 0を返す"
[[ $str =~ 23[[:blank:]]abc ]] && echo "[[ \$str =~ 23[[:blank:]]abc ]] : 0を返す"
echo ""式に関する演算子"
[[ ! ( $n && $s && $s == "123" ) && ! $s == "abcd" ]] \
&& echo "[[ ! ( \$n && \$s && \$s == \"123\" ) && ! \$s == \"abcd\" ]] : 0を返す"
n=0 ; [[ $(( ++n )) && $(( ++n )) ]] \
&& echo "[[ \$(( ++n )) && \$(( ++n )) ]] --- \$n = $n --- 0を返す"
n=0 ; [[ $(( ++n )) || $(( ++n )) ]] \
&& echo "[[ \$(( ++n )) || \$(( ++n )) ]] --- \$n = $n --- 0を返す"
n=0 ; [[ ( $s == "123" ) && $(( ++n )) ]] \
|| echo "[[ ( \$s == \"123\" ) && \$(( ++n )) ]] --- \$n = $n --- 1を返す"
n=0 ; [[ ( $s == "123" ) || $(( ++n )) ]] \
&& echo "[[ ( \$s == \"123\" ) || \$(( ++n )) ]] --- \$n = $n --- 0を返す"
実行結果
$ ./sample7.sh
n = 123
s = abc
算術比較の実行
[[ $n -eq 123 ]] : 0を返す <--- -eq : 数値が等しければtrue。式がtrueなので結果として0を返す
[[ $n -ne 123 ]] : 1を返す <--- -ne : 数値が等しくなければtrue。式がfalseなので結果として1を返す
文字列比較の実行
[[ $s == "abc" ]] : 0を返す <--- 文字列が等しければtrue。式がtrueなので結果として0を返す
[[ $s != "abc" ]] : 1を返す <--- 文字列が等しくなければtrue。式がfalseなので結果として1を返す
ファイルの存在確認の実行
$0 = ./sample7.sh
[[ -f "$0" ]] : 0を返す <--- ファイルが存在するとtrue。式がtrueなので結果として0を返す
パターンマッチング
[[ $0 == *.sh ]] : 0を返す <--- 演算子「==」で文字列がパターン(右辺)にマッチすると0を返す
[[ $0 == *[.,@]sh ]] : 0を返す <--- 「[...]」による任意文字指定も可能
[[ $str == 123[[:blank:]]abc ]] : 0を返す <--- 「[...]」の間で文字クラスの指定も可能
[[ $str != 23[[:blank:]]abc ]] : 0を返す <--- 演算子「!=」はマッチしない場合に0を返す
正規表現によるパターンマッチング
[[ $0 =~ ^.+\.sh$ ]] : 0を返す <--- 演算子「=~」により正規表現によるパターンマッチが可能
[[ $0 == *[.,@]sh ]] : 0以外を返す <--- パターンマッチしない場合は1、正規表現が間違いの場合は2を返す
[[ $str =~ "23 abc" ]] : 0を返す <--- 引用符を使用した文字列の指定も可能
[[ $str =~ 23[[:blank:]]abc ]] : 0を返す <--- 文字クラスの指定も可能
式に関する演算子
式に関する演算子
[[ ! ( $n && $s && $s == "123" ) && ! $s == "abcd" ]] : 0を返す <--- 演算子&& : 全体の結果はtrue
[[ $(( ++n )) && $(( ++n )) ]] --- $n = 2 --- 0を返す <--- 演算子&& : 両方の++nが実行される
[[ $(( ++n )) || $(( ++n )) ]] --- $n = 1 --- 0を返す <--- 演算子|| : 最初の++nが実行されtrueとなり次の++nは実行されない
[[ ( $s == "123" ) && $(( ++n )) ]] --- $n = 0 --- 1を返す <--- 演算子&& : 最初の式の評価がfalseとなるため次の++nは実行されない。全体の結果もfalse
[[ ( $s == "123" ) || $(( ++n )) ]] --- $n = 1 --- 0を返す <--- 演算子|| : 最初の式の評価がfalseとなるが次の++nは実行される。全体の結果はtrue
( 式 ) : 演算子の通常の優先度を変更。「式」の値を返す
! 式 : 「式」がfalseのときtrue
式1 && 式2 : 「式1」と「式2」の両方がtrueであればtrue
式1 || 式2 : 「式1」と「式2」のどちらかがtrueであればtrue
式1の値のみで条件式全体の戻り値が決定される場合、式2は評価されない
sample8.sh
#!/bin/bash
echo "for 変数名"
for a
do
echo "$a"
done
echo
files=( $(cat sample8.txt) )
n=0
echo "for 変数名 in ... ;"
for a in ${files[@]}
do
n=$(( ++n ))
echo "$n行目 $a"
done
echo
echo "for (( 式1 ; 式2 ; 式3 ; )) ;"
for (( i=0 ; i < ${#files[@]} ; ++i ))
do
echo "$(( i+1 ))行目 ${files[i]}"
done
sample8.txt
line1
line2
line3
実行結果
$ ./sample8.sh arg1 arg2
for 変数名
arg1 <--- 「in ...」が無い場合は、設定された位置パラメータを順次変数にセット
arg2 セットされた位置パラメータごとにdo~done間を実行
for 変数名 in ... ;
1行目 line1 <--- 「in ...」に続く単語を展開したリストを順次変数にセット
2行目 line2 リストの要素ごとにdo~done間を実行
3行目 line3
for (( 式1 ; 式2 ; 式3 ; )) ;
1行目 line1 <--- 式1評価後、式2の評価が0となるまで、do~done間の実行と式3評価を実行
2行目 line2
3行目 line3
sample9.sh
#!/bin/bash
# 入力プロンプトの設定
PS3="番号で選択してください : "
echo "selectテスト(1)"
echo "in ... 無し"
echo "位置パラメータから選択肢を生成"
select s
do
echo "REPLY = $REPLY"
echo "s = \"$s\""
if [[ $s ]]; then
# 正しい選択肢を選択した場合は終了
break
fi
done
echo "選択された値 : $s"
echo
echo "selectテスト(2)"
echo "in ... 有り"
echo "in ... から選択肢を生成"
n=0
select s in 加算 リセット 終了
do
if [[ $s == "終了" ]]; then
# 終了を選択した場合は終了
echo "終了"
break
elif [[ $s == "加算" ]]; then
n=$(( ++n ))
else
n=0
fi
echo "n = $n"
done
echo
sample9.txt
選択肢a
選択肢b
選択肢c
実行結果
$ ./sample9.sh $(cat sample9.txt)
selectテスト(1)
in ... 無し
位置パラメータから選択肢を生成
1) 選択肢a <--- 位置パラメータに設定されたsample9.txtの各行の文字列
2) 選択肢b 「1)」などの番号は自動的に付加される
3) 選択肢c
番号で選択してください : <--- PS3に設定されたプロンプト
1) 選択肢a <--- 空入力の場合は再度選択肢リストを出力
2) 選択肢b
3) 選択肢c
番号で選択してください : a
REPLY = a <--- 読み込まれた入力値は変数REPLYに保存
s = "" <--- 対応する選択数値以外の入力は、指定変数に選択文字列が設定されない
番号で選択してください : 1
REPLY = 1
s = "選択肢a" <--- 対応する選択数値の入力は、指定変数に選択文字列が設定される
選択された値 : 選択肢a
selectテスト(2)
in ... 有り
in ... から選択肢を生成
1) 加算 <--- in ... から単語分割され、番号が自動付加された文字列を出力
2) リセット
3) 終了
番号で選択してください : 1
n = 1
番号で選択してください : 1
n = 2
番号で選択してください : 2
n = 0
番号で選択してください : 1
n = 1
番号で選択してください : 1
n = 2
番号で選択してください : 3
終了
sample10.sh
#!/bin/bash
echo "マッチングパターン例(1)"
case "$1" in
a*)
echo "1文字目a" ;;
b*)
echo "1文字目b" ;;
c*)
echo "1文字目c" ;;
esac
echo
echo "マッチングパターン例(2)"
echo "「|」区切りによる記述"
case "$1" in
a* | b* | c* | d* | e*)
echo "1組" ;;
f* | g* | h* | i* | j*)
echo "2組" ;;
k* | l* | m* | n* | o*)
echo "3組" ;;
*)
echo "4組" ;;
esac
echo
echo "リストの終端が「;;&」"
case "$1" in
a*)
echo "1文字目a" ;;&
?a*)
echo "2文字目a" ;;&
??a*)
echo "3文字目a" ;;&
???a*)
echo "4文字目a" ;;
esac
echo
echo "リストの終端が「;&」"
case "$1" in
a*)
echo "a出現後処理(1)" ;&
?a*)
echo "a出現後処理(2)" ;&
??a*)
echo "a出現後処理(3)" ;&
???a*)
echo "a出現後処理(4)" ;;
esac
実行結果
$ ./sample10.sh baca
マッチングパターン例(1)
1文字目b <--- 1文字目の「b」がマッチ
リストの終端が「;;」の場合、1度マッチすると以降のマッチングは実行されない
マッチングパターン例(2)
「|」区切りによる記述
1組 <--- 1文字目の「b」が「|」区切りからなる1組目にマッチ
リストの終端が「;;」の場合、1度マッチすると以降のマッチングは実行されない
リストの終端が「;;&」
2文字目a <--- 次のパターンに対するマッチングが実行される
4文字目a <---
リストの終端が「;&」
a出現後処理(2) <--- マッチして対応した処理が実行された場合、次のパターンに対応した処理も実行される
a出現後処理(3) <---
a出現後処理(4) <---
sample11.sh
#!/bin/bash
[[ $# -gt 1 ]] && echo "[[ \$# -gt 1 ]] : 終了ステータス0"
[[ $# -eq 1 ]] && echo "[[ \$# -eq 1 ]] : 終了ステータス0"
echo
if [[ $# -gt 1 ]]; then
echo "引数リスト"
for a
do
echo "$a"
done
elif [[ $# -eq 1 ]]; then
echo "引数 : $1"
else
echo "引数無し"
fi
実行結果
$ ./sample11.sh <--- 引数無し
引数無し
$ ./sample11.sh arg1 <--- 1つの引数
[[ $# -eq 1 ]] : 終了ステータス0
引数 : arg1
$ ./sample11.sh arg1 arg2 <--- 2つの引数
[[ $# -gt 1 ]] : 終了ステータス0
引数リスト
arg1
arg2
sample12.sh
#!/bin/bash
# 「$#」が0より大きければ実行
while [[ $# -gt 0 ]]
do
echo "$1"
shift
done
実行結果
$ ./sample12.sh arg1 arg2 <--- 2つの引数
arg1
arg2
$ ./sample12.sh arg1 arg2 arg3 <--- 3つの引数
arg1
arg2
arg3
sample13.sh
#!/bin/bash
# 「$#」が1より小さくなるまで実行
until [[ $# -lt 1 ]]
do
echo "$1"
shift
done
実行結果
$ ./sample12.sh arg1 arg2 <--- 2つの引数
arg1
arg2
$ ./sample12.sh arg1 arg2 arg3 <--- 3つの引数
arg1
arg2
arg3
sample14.sh
#!/bin/bash
# 関数名()
samplefunc1()
{
echo "samplefunc1()"
while [[ $# -gt 0 ]]
do
echo "$1"
shift
done
echo
}
# function 関数名
function samplefunc2
{
echo "function samplefunc2"
until [[ $# -lt 1 ]]
do
echo "$1"
shift
done
echo
}
# function 関数名 複合コマンド リダイレクト
function samplefunc3
{
echo "function samplefunc3 複合コマンド リダイレクト"
until [[ $# -lt 1 ]]
do
echo "$1"
shift
done
echo
} > sample14.txt
# 関数呼び出し
samplefunc1 arg1 arg2
samplefunc2 arg1 arg2 arg3
samplefunc3 "$@"
echo "関数外"
for a
do
echo "$a"
done
実行結果
$ ./sample14.sh arg1 arg2 arg3 arg4 <--- 4つの引数で実行
samplefunc1()
arg1 <--- 関数内の新規位置パラメータ
arg2 <---
function samplefunc2
arg1 <--- 関数内の新規位置パラメータ
arg2 <---
arg3 <---
関数外
arg1 <--- シェルスクリプト起動時の4つの引数
arg2
arg3
arg4
$ cat sample14.txt <--- リダイレクトにより出力
function samplefunc3 複合コマンド リダイレクト
arg1 <--- 関数内の新規位置パラメータ($@を引数にして呼び出し)
arg2 <---
arg3 <---
arg4 <---
実行環境
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
コード例・出力内容中の表記
・実行例中の太字表記部分は、コマンドなどの入力された文字列を示します。
・「︙」や「...」の着色省略表記は、 実際のソースコードや出力内容などを省略加工した部分を示します。
・「︙」や「...」の着色省略表記は、 実際のソースコードや出力内容などを省略加工した部分を示します。