シェル(sh)Tips

シェルのTipsと言える程の内容ではないかもしれませんがそれらしいものの備忘録です。一応、shを元に書いているのでおそらく殆どの環境では大丈夫だと思います。ただ、FreeBSDが主ですので、Linuxの方はコマンドが異なる場合があるかもしれません。知っているところでは、lineというコマンドがFreeBSDにはありませんでした。

時間の取得
時間の取得はdateコマンドを使って行ないます。ここで指定しているフォーマットは4桁の年、2桁の月、2桁の日にちとなってます(例.20050808)
詳しくはマニュアルを参照してみてください。

■今日の日付をフォーマットを指定して取得する
suffix=`date "+%Y%m%d"`

■前日の日付をフォーマットを指定して取得する
suffix=`date -v -1d "+%Y%m%d"`
             ~~~~~~
              ↑取得時間の補正(この場合、1日前になる)

■年月日の取得
timestr_day=`date "+%Y%m%d"`

■年月の取得
timestr_month=`date "+%Y%m"`

■年の取得
timestr_year=`date "+%Y"`

■時分秒の取得
timesrt_time=`date "+%H%M%S"`
ページのトップへ

オプション引数の処理
オプション引数はコマンドの後に続く"-"から始まっている文字のことです。これをシェル側で処理するにはgetoptという組み込みコマンド(Builtinコマンド)を利用して行います。ちなみに、このコマンドはcshでは利用できないらしいですのでご注意下さい(実はこれで数日、嵌りました)
たぶん良くある記述方を以下に記載しています。getoptsコマンドの後に記載している文字が受け取るオプションの文字になります。文字の後ろに':(コロン)'をつけると値(-o parameterなど)を持ったオプションという意味になり、${OPTARG}に値が格納されるようになります。以下の場合では"a"はパラメータ付きオプションで、"b"はパラメータの付かないオプションとなります。

  while getopts a:b arg
  do
      case ${arg} in
      a)
          # パラメータありのオプション処理
          arg="${OPTARG}"
          ;;
      b)
          # パラメータなしのオプション処理
          b=1
          ;;
      *)
          ~上記に該当しない条件の処理~
          exit 1;;
      esac
  done
ページのトップへ

オプション以外の引数の取得
${OPTIND}変数には値を含めたオプションの個数が格納されていますが、そのままシフトすると1個多く移動してしまうので1を引いた分だけシフトすることになります。

if [ $# -gt 1 ]
then
    shift $((${OPTIND}-1))
fi
ページのトップへ

ファイルサイズの取得
lsに詳細表示のオプションをつけて得られたデータをawkを使って取得しています。

filesize=`ls -l ${file} | awk '{print $5}'`
ページのトップへ

コンソールから入力を受け取る
readコマンドは文字は取得したデータを格納するための変数名を指定して使用します。

out=""

echo "文字を入力してください"
read out
echo "${out}"
ページのトップへ

関数の定義と呼出
returnされた値はステータスコードとして$?変数に格納されます。関数からの出力を得たい場合はechoやprintfなどの文字を表示するコマンドを使用することで行えます。

■定義
function(){
    ls -la

    return 0
}
※returnした状態は$?変数に入る。
■定義(引数指定された場合。sh:$1-$9)
function(){
    ls -$1

    return 0
}
※returnした状態は$?変数に入る。
■定義(文字を返す場合)
function(){
    echo $1

    return 0
}
※returnした状態は$?変数に入る。
■呼び出し
function
■呼び出し(引数指定)
function"a"
■呼び出し(関す内でechoされた文字を代入する)
res=`functino "a"`
【使用例】
isdir(){
    if [ "$1" -a -d "$1" ]
    then
        return 1
    else
        return 0
    fi
}

isdir $1
if [ $? -eq 1 ]
then
    echo "directory."
else
    echo "not directory."
fi
ページのトップへ

空白文字を含むファイルの読み取り
for文では空白文字を区切り文字として認識してしまうためreadを使って処理を行います。

cat ${tempfile} | \
while read line
do
    echo "[${time}] ${line}" >> ${logfile};
done
ページのトップへ

ユーザー名を1つずつ取得
for uname in `cat /etc/passwd | grep "_..:" | cut -d ':' -f '1'`
do
	# 末尾の空白の除去
	uname=`echo -n ${uname}`

	~処理~
done
※複数行のデータをforで処理する場合は\nまたは空白が区切り文字となる
ページのトップへ

整数の計算
■足し算
i=`expr ${i} + 1`
■引き算
i=`expr ${i} - 1`
■掛け算
i=`expr ${i} \* 2`
■割り算
i=`expr ${i} / 2`
ページのトップへ

if文を一行で書く
メインの処理だと1行にすると可読性が失われるかもしれませんが、デバックなどのメッセージ表示させるときは1行の方が目立ちにくく全体が纏まるので個人的には重宝しています。載せる必要も無いかもしれませんが、よくセミコロンの位置を間違える私にとっては欠かせません。

if [ 1 ]; then ~処理~; else ~処理~; fi
ページのトップへ

外部から別のファイルを読み込む
.(ドット)のあとに読み込むスクリプトファイルを指定します。ただし、読み込んだスクリプトファイル内に同じ名前の変数があると上書きされてしまうので注意が必要です。もしかするとこれは固有かもしれませんが、文末にセミコロンが付いていたり、最終行を空白にするとエラーになります。

. script.sh
  ~~~~~~~~~
   ↑スクリプトファイル
ページのトップへ

telnetなどのコマンドに複数の命令を処理をさせる
複数の命令を渡すには()でコマンドをグループにしてそれをパイプでtelnetへ渡します。

(
      ~処理~
) | telnet アドレス ポート
ページのトップへ