Bourneシェル、実際にはBashでシェルスクリプトを書くための備忘録
Bashのバージョンを確認する
echo $BASH_VERSION # 3.2.57(1)-release
カレントディレクトリのフルパスを取得する
echo $PWD
部分文字列を取り出す
letters='abcdefghijklmnopqrstuvwzyz'
echo ${letters:0:4} # 0から数えて0番目から4文字を取り出す; abcd
echo ${letters:7:16} # 0から数えて7番目から16文字を取り出す; hijklmnopqrstuvw
echo ${letters:9} # 0から数えて9番目から最後までを取り出す; jklmnopqrstuvwzyz
文字列を比較する
proverb='A ship in the harbor is safe, but that is not what a ship is for.'
word=${proverb:2:4}
if [ $word != 'SHIP' ]; then # 等価の場合は =
echo $word
fi
数値を比較する
if [ $? -eq 0 ]; then # -eq, -ne, -gt, -ge, -lt, -le
echo identical
fi
文字列が空か1文字以上あるかをテストする
arg1=$1 # 第1コマンド引数からテストしたい文字列を取得
if [ -n "$arg1" ]; then # ダブルクオートで囲うことが重要; 1文字以上の長さがあったら
echo 'more than 0 characters (-n)'
else
echo '0 character (-n)'
fi
if [ -z $arg1 ]; then # ダブルクオートで囲まなくてもいい; 文字列長が0であったら
echo '0 character (-z)'
else
echo 'more than 0 characters (-z)'
fi
exit
ファイル名からパスや拡張子を取り除いた文字列を取得する
file_name=`basename /etc/ssh/ssh_host_rsa_key.pub` # ssh_host_rsa_key.pub
file_name=`basename /etc/ssh/ssh_host_rsa_key.pub .pub` # ssh_host_rsa_key
実行されているスクリプト自身が保存されているパスを取得する
prefix=`dirname $(readlink $0 || echo $0)`
echo $prefix
コマンド引数の数を取得する。
echo $# # コマンド自体は含まず、コマンドオプションやコマンド引数の総数が $# に入っている
最終コマンド引数を取得する。
echo ${@:$#}
キーボードからの入力を促がす
read -p 'Type any string. ' str
echo $str
forループのために便利なコマンドseqを使う
seq 11
seq 52 7 # 1ずつ減らしながら52以下7以上の全ての整数を表示
seq -f "%03g" 3 372 # 数字の前に0を加えて桁を揃えて表示
正規表現を使ってみる
mkdir test_{a,b,c,d,e,f,g,h}
for dir in test_*
do
cd $dir/
if [[ $PWD =~ ^.+_[c-f]$ ]]; then # 名前の末尾が _c, _d, _e, _f のいずれかであるディレクトリを判定
pwd # .+ のところを [¥/¥w]+ と書いたら意図した通りに動作しなかったので要注意
else
date
fi
cd ../
done
rm -fr test_?/
exit
# 出力結果
# Fri Jul 21 15:43:54 JST 2017
# Fri Jul 21 15:43:54 JST 2017
# /tmp/test_c
# /tmp/test_d
# /tmp/test_e
# /tmp/test_f
# Fri Jul 21 15:43:54 JST 2017
# Fri Jul 21 15:43:54 JST 2017
=~ は使えるが !~ は使えない。
タブや改行を出力する
echo -e "foo\tbar\nbaz\tqux"
配列を使ってみる
var=(`cat variables.txt`) # テキストファイルに1行ごとに書かれた空白類文字を含まない文字列を配列に
for variable in ${var[@]} # 配列の全ての要素に対して処理
do
echo $variable
done
declare -a names=("Alice" "Bob" "Carol" "David") # この場合 " 省略可
declare -a years=(1985 1989 1995 1996)
echo ${#names[@]} # 配列のサイズ 4
echo ${#years[@]} # 配列のサイズ 4
for i in {0..3} # 配列のindexは0-based; {0..3} 0から3を含んで3まで
do
echo -e "$i\t${names[$i]}\t${years[$i]}"
done
関数を定義してみる
function prepare_array()
{
list=(`seq $1`) # $1はこの関数の第1引数; 関数に戻り値は無い
}
if [ ! -z $2 ]; then # 第2コマンド引数があれば処理を実行
up_to=$2
prepare_array $up_to # その値を引数に関数呼び出し
for element in ${list[@]} # 戻り値は無いが、関数内で定義された変数が利用できる
do
printf " %s" $element
done
echo
fi
直前のコマンドのプロセスIDを取得する
sleep 1024 &
previous_pid=$!
ファイルサイズが0か否かを確認する
if [ -s $1 ]; then # 変数が定義されているか否かも -s で確認可能
:
else
rm $1
fi
その他のファイルテスト演算子: -e 存在するか; -d ディレクトリか; -f 通常のファイルか
ファイルが同一か否かを確認する
cmp foo bar
if [ $? -eq 0 ]; then
echo identical
else
echo different
fi
否定、論理和、論理積を使う
if [ \( ! -e foo \) -a \( -e bar \) ]; then
echo 1
elif [ \( ! -e foo \) -o \( -e bar \) ]; then
echo 2
else
echo 3
fi
整数値をインクリメントする
i=95
while :
do
echo $((i++))
if [ $i -gt 105 ]; then
exit $i
fi
done
j=0
let j++
echo $j # 1
let j+=8
echo $j # 9
簡単な計算をする
alice=57
generation=10
echo $(($alice / $generation)) # 5 商
echo $(($alice % $generation)) # 7 剰余
乱数を取得する
echo $RANDOM # 19168 (0から32767までの値)
echo $(($RANDOM % 10000 + 50000)) # 53478 (確率は一様でないながら50000から59999までの乱数を取得)