Skip to main content

bash

bashスクリプト等でよく使う機能の利用パターンを記載。

trap

When the script exits, remove tmpfile

tmpfile=/tmp/tmpfile.$$
trap "rm ${tmpfile}" EXIT

basename, dirname

use script file name and directory in the script

echo $(basename $0 .sh)
echo $(dirname $0)

pushd, popd

pushd、popdは標準出力にメッセージを吐く。スクリプトで使用する際は不要なので捨てる。

pushd . > /dev/null
cd dir
:
popd    > /dev/null

read

標準入力からの入力を変数dummyへ入れる。 (-pでプロンプトを指定。-sを指定するとエコーバックしない)

read -p "input? " [-s] dummy

比較演算

条件を満たせばtrue

演算子 説明
-z 文字列の長さ0
-n 文字列の長さ1以上
-s ファイルサイズが1以上

if

文字列の比較

if [ $str = "hoge" ]; then
:
else
:
fi

case

case "$?" in
  0)
    echo ok
    ;;
  1)
    echo ng
    ;;
  *)
    echo error
    ;;
esac

for loop

for file in /etc/ssh/ssh_host*key* ; do
:
done

while loop

条件がtrueの時だけ実行する。

while true; do
:
sleep 300
done

全ての引数に対して処理を実行する。

while [ $1 ]; do
echo $1
shift
done

while とread

while read line; do
echo $line
done < filename

または

cat filename | while read line; do
echo $line
done

printf

printf 'INSERT INTO mytable (temprature, humidity) VALUES (%f, %f);' 20.0 50.0 | sqlite3 database.db

組み込みコマンドgetoptsの使い方の例

#! /bin/bash

while getopts "hw:" opt; do
  case ${opt} in
    h)
      echo usaage
      exit
      ;;
    w)
      dow=${OPTARG}
      ;;
  esac
done
shift $((OPTIND - 1))

while [ $1 ]; do
  :
  shift
done

indirection reference

using shell

key=slackpkg
pkg_slackpkg=skackware
myos=pkg_${key}
echo ${!myos}

using eval

pkg_slackpkg=slackware
key=slackpkg
eval myos=\"\${pkg_${key}}\"
echo ${myos}

when variable is array

pkg_apt=(debian ubuntu raspbian)
pkg_yum=(rhel fedora centos)

for key in apt yum; do
  echo ${key}
  for i in `seq 0 2`; do
    eval myos=\"\${pkg_${key}[i]}\"
    echo ${i}: ${myos}
  done
done

その他

スクリプトの改行文字をCR+LFで書くと、CRが(shebang等の)コマンド(の一部)として認識され、実行エラーとなる。 スクリプトの改行文字はLFで書く。

$ bash myscript.sh
: command not found
$ chmod +x myscript.sh
$ ./myscript.sh
-bash: ./myscript.sh: /bin/bash^M: bad interpreter: そのようなファイルやディレクトリはありません

When shebang is omitted though it has executable permission (+x), when it called without shell command it may show below error message

exec user process caused "exec format error"

rename the file using a part of original file name.

$ ls | tail -4 | awk -F_ '{print "mv",$0, "foo_"$4}'