7
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

馬鹿の一つ覚え: Bashでシェルスクリプト

Last updated at Posted at 2017-07-21

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までの乱数を取得)
7
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?