Top/Lang/shell/bash

目次

変数

代入

削除 unset

unset val1                # 変数の削除
unset array[0] array[3]   # 配列から、特定の要素のみを削除
unset array               # 要素指定無しで配列を指定した場合、その配列全体を削除

連番の数値を自動生成する

$ echo {1..10}
1 2 3 4 5 6 7 8 9 10

$ echo {10..1}
10 9 8 7 6 5 4 3 2 1

配列

初期化

A=()
A=( 1 2 3 4 )

追加

部分配列の取り出し

書式

A=( 0 1 2 3 4 5 6 )
echo ${A[@]:2:4}     # 実行結果: 2 3 4 5
echo ${A[@]:2}       # 実行結果: 2 3 4 5 6
echo ${A[@]::2}      # 実行結果: 0 1

特殊変数

環境変数

変数意味
$0シェル、あるいはプログラムの名前
$1 $2 ...引数
$@引数の配列
$*
$#引数の数
$-シェルの呼出し時に指定されたオプション
$_前のコマンドの最後の引数
$!最後に起動したバックグラウンドジョブのPID
$?最後に実行したコマンドや関数のRETURN値
$$そのプロセスのPID

その他の特殊変数

変数意味
${#val}${val[0]} の長さ(文字列としてみた場合の文字数に相当)
${#val[N]}${val[N]} の長さ(文字列としてみた場合の文字数に相当)
${#val[@]}配列${val[@]} の配列数

変数と環境変数

match

変数 ${hoge} に対して

書法意味備考
${hoge%<ptrn>}末尾から見て、<ptrn> に最も短く一致する部分を取り除いた値
${hoge%%<ptrn>}末尾から見て、<ptrn> に最も長く一致する部分を取り除いた値
${hoge#<ptrn>}先頭から見て、<ptrn> に最も短く一致する部分を取り除いた値
${hoge##<ptrn>}先頭から見て、<ptrn> に最も長く一致する部分を取り除いた値
${hoge/<ptrn>/<str>}${hoge} の値で<ptrn>に最も長く一致する最初の部分だけを<str>で置換する<ptrn>が # で始まる場合は、hoge の先頭と一致しなければならない
<ste>がNULLの場合は、一致した部分が削除される。
${hoge//<ptrn>/<str>}${hoge} の値で<ptrn>に一致する部分全てを<str>で置換する

FULLPATH=/home/user/file_name.ext
PATH=${FULLPATH%/*}		# パス部分を表示
FNAME=${FULLPATH##*/}		# ファイル名以下を表示
FNAME_ONLY=${FULLPATH%.*}	# ファイル名のみを表示
DOTEXT=${FULLPATH##*.}		# 拡張子を表示

パス文字列操作

パスからファイル名を取得する - basename

パスからディレクトリ部分を取得する - dirname

置換演算子

変数 val に対して

書法意味備考
val が存在しNULLでない場合左以外の場合
${val:-word}valを返すwordを返す
${val:=word}valを返すvalにwordを設定して返す位置パラメータや特殊なパラメータは除く
${val:?msg}valを返すval の後にmsgを出力し、現在のコマンド或はスクリプトを中止する(対話型シェルではない場合)
msgを省略すると "parameter null or not set" を出力する。
${val:+word}wordを返すNULLを返す
${val:offset}サブ文字を展開する。
offsetの位置からlength文字の長さのサブ文字r列をvalから取り出す。
文字の位置は0からカウントする。
lengthが省略された場合は、offsetからvalの最後までが展開の対象になる。
offsetが負値の場合、開始位置はvalの終端からカウントされる。
valが@の場合、lengthはoffsetを先頭とする位置パラメータの番号になる。
${val:offset:length}

評価

文字列評価

記号意味
-z <string><string> の長さが 0 ならば真
-n <string><string> の長さが 0 でなければ真
string1 == string2文字列が同じならば真。== の代わりに = でも可
tring1 != string22 つの文字列が異なれば真
string1 < string2現 在のロケールにおいて、string1 が string2 よりも辞書順で前にある場合に真
string1 > string2現在のロケールにおいて、string1 が string2 よりも辞書順で後に ある場合に真

Cのstrlen() 的使い方をしたいとき

ファイル属性

記号意味
-d <file><file>が存在し、且つディレクトリである
-e <file><file>が存在する
-f <file><file>が存在し、且つ通常ファイルである
-h <file><file>が存在し、且つシンボリックリンクである
-r <file><file>にreadパーミッションが与えられている
-s <file><file>が存在し、且つ空ではない
-w <file><file>にwriteパーミッションが与えられている
-x <file><file>にexecuteパーミッションが与えられている
-O <file><file>の所有者である
-G <file><file>のグループIDが自分のものと一致する(複数のグループに属している場合はそのいずれかと一致する)
<file1> -nt <file2><file1>が<file2>よりも新しい(ファイル変更時刻を比較)
<file1> -ot <file2><file1>が<file2>よりも古い(ファイル変更時刻を比較)

数値評価

記号意味
arg1 -eq arg2arg1 が arg2 に対して等しい
arg1 -ne arg2arg1 が arg2 に対して等しくない
arg1 -lt arg2arg1 が arg2 に対して小さい
arg1 -le arg2arg1 が arg2 に対して小さいか、等しい
arg1 -gt arg2arg1 が arg2 に対して大きい
arg1 -ge arg2arg1 が arg2 に対して大きいか、等しい

※ arg1, arg2 には、正または負の整数を使用出来る。

フロー制御

if

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

for

for i in "${val_list[@]}"; do
    処理

    if [ 次ループへ飛ぶ条件 ]; then
        continue;
    fi

    if [ ループ終了条件 ]; then
        break;
    fi
done

index を使う

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

コマンドの実行結果を for ループ条件にする

for val in $(<command>); do
    処理
done

自動連番でループを回す

for i in {1..10}; do
    処理
done

とすれば出来る。但し、上の例の {1..10} はダブルクォートで括ってはいけないので注意!

数列の自動生成(seq) を使う

while

while [ 条件 ]; do
    処理

    if [ 次ループへ飛ぶ条件 ]; then
        continue;
    fi

    if [ ループ終了条件 ]; then
        break;
    fi
done

case

case ${i} in
word_1 )
    処理1
    ;;
word_2 )
    処理2
    ;;
* )
    上記どの条件にも当てはまらない場合に行う処理
    ;;
esac

echo の出力先

printf

改行

pipe

alias を含むコマンドライン

pipe で繋がれたコマンドラインの各マンドの終了ステータスを取得する - PIPESTATUS

算術式を扱う

expr を使わない

(( sum = $a + $b ))    # addition
(( sub = $a - $b ))    # subtraction
(( mul = $a * $b ))    # multiplication
(( div = $a / $b ))    # division
(( mod = $a % $b ))    # modulo (remainder)
(( exp = $a ** $b ))   # exponentiation

expr を使う

sum=$(expr $a + $b  )   # addition
sub=$(expr $a - $b  )   # subtraction
div=$(expr $a / $b  )   # division
mod=$(expr $a % $b  )   # modulo (remainder)

参考リンク

shell script の debug

-x オプション

-v オプション

呼び出し元の関数名を取得 - FUNCNAME

呼び出し元の行番号を取得 - BASH_LINENO

ログ関数の実装例

function log_print {
    local readonly msg="${@}";
    local readonly func=${FUNCNAME[1]};
    local readonly line=$(printf "%04d" ${BASH_LINENO[0]});
    echo "${line}: ${func}: ${msg}";
    # printf で複数の値を一度にフォーマットすることは出来ない。
}

ini ファイル形式のデータを読む

function get_section_from_ini_file {
    # 指定された ini file 形式のファイルから、指定されたセクションの内容を取り出し出力する
    local ini_file=${1};
    local section=${2};
    sed -e 's/[[:space:]]*\=[[:space:]]*/=/g' \
    -e 's/;.*$//' \
    -e 's/[[:space:]]*$//' \
    -e 's/^[[:space:]]*//' \
    -e "s/^\(.*\)=\([^\"']*\)$/\1=\"\2\"/" \
   < ${ini_file} \
    | sed -n -e "/^\[${section}\]/,/^\s*\[/{/^[^;].*\=.*/p;}";
}

組み込みコマンド

local <val>

readonly <val>

local readonly <val>

Scripts

llast

#!/bin/bash
TARGET=${1};
TARGET_FILE=`ls -1tr | tail -${TARGET} | head -1`

echo ${TARGET_FILE};

findd

#!/bin/bash
# find ${@} find -printf "%AY-%Am-%Ad %p\n";    # 最後にアクセスした日付を併記
find ${@} -printf "%TY-%Tm-%Td %p\n";            # 最後に修正した日付を併記

トラブルシューティング

/bin/sh: 警告: シェルレベル (1000) は高すぎます。1に再設定されました


トップ   編集 凍結 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2024-04-21 (日) 14:16:09