1
0

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 5 years have passed since last update.

ShellScriptに入門する(3日目)

1
Last updated at Posted at 2019-08-11

今日もやっていきましょう(自作Script作ってたら日をまたいでた...)

ShellScriptに入門する(1日目)
ShellScriptに入門する(2日目)
ShellScriptに入門する(3日目)
ShellScriptに入門する(4・5・6日目)

関数を勉強し忘れてたので関数から...

関数

関数のスコープ

関数が呼ばれたことによって関数内で$@パラメータの値が変わっている
ただし変数xはグローバル変数であるため、関数内で値が変更されたあとにもその値が反映されている

func_scope.sh
# !/bin/sh

myfunc()
{
  echo "I was called as : ${@}"
  x=2
}

echo "Script was called with ${@}"
x=1
echo "x is ${x}"
myfunc 1 2 3
echo "x is ${x}"
% chmod 755 func_scope.sh; sh func_scope.sh a b c
Script was called with a b c
x is 1
I was called as : 1 2 3
x is 2

再帰

以下のScriptは再帰処理によって階乗を求めている

factorial.sh
# !/bin/sh

factorial()
{
  if [ "${1}" -gt "1" ]; then
    i=`expr ${1} - 1`
    j=`factorial ${i}`
    k=`expr ${1} \* ${j}`
    echo $k
  else
    echo 1
  fi
}

while :
do
  echo "Enter a number:"
  read x
  factorial $x
done
% chmod 755 factorial.sh; sh factorial.sh
Enter a number:
3
6
Enter a number:
5
120
Enter a number:
0
1
Enter a number:
^C

別ファイルで定義された関数を読み込む

common.libで定義した関数をfunction2.shで読み込んで呼び出している
また、稀によくみる拡張子libがlibraryの略だったのを知れたのは大きな収穫となった
C言語とかで使われてるらしい

common.lib
STD_MSG="About to rename some files ..."

rename()
{
  # expects to be called as: rename .txt .txt.bak
  FROM=${1}
  TO=${2}

  for i in *$FROM
  do
    j=`basename $i $FROM`
    mv $i "${j}$TO"
  done
}
function2.sh
# !/bin/sh
# function2.sh
. ./common.lib
echo "${STD_MSG}"
rename txt txt.bak
% touch hoge.txt
% ls | grep "hoge"
hoge.txt
% chmod 755 function2.sh; sh function2.sh
About to rename some files ...
% ls | grep "hoge"
hoge.txt.bak

自作Script紹介(cron生成Script)

今度こそScript作成に必要な文法は舐められたと思うので、Scriptを作成してみた
作成したScript
対話形式でcronが生成できるようなScript(連想配列を使いたかったのでzshを使用している)
作りながらhoge日~fuga日に渡って実行するようなcronなどが生成できないことに気づいたので今後修正を加えていく

gen_cron.sh
gen_cron.sh
# ! /usr/bin/zsh
. ./common.lib
typeset -g -A hash
hash=(min \* hour \* day \* month \* week \*)

typeset -a isErrday
while [ "${isErrday}" != y ] && [ "${isErrday}" != N ]
do
  echo "毎日を指定しますか? y/N [ y ]"
  read isErrday
  if [ -z "${isErrday}" ]; then
    isErrday=y
  fi
  if [ "${isErrday}" != y ] && [ "${isErrday}" != N ]; then
    echo "y/Nで選択してください"
  fi
done

if [ "${isErrday}" = N  ]; then
  checkDateOrWeek hash
fi

setTime hash

typeset -a command
while [ -z "${command}" ]
do
  echo "設定したいコマンドを入力してください"
  read command
done

cron="${hash[min]} ${hash[hour]} ${hash[day]} ${hash[month]} ${hash[week]} ${command}"
echo "${cron}"
common.lib
common.lib
checkDateOrWeek()
{
  typeset -a dateOrWeek
  while [ "${dateOrWeek}" != date ] && [ "${dateOrWeek}" != week ]
  do
    echo "日付を指定しますか? 曜日を指定しますか? date/week [ date ]"
    read dateOrWeek
    case "${dateOrWeek:=date}" in
      date)
        setDate hash
        ;;
      week)
        setWeek hash
        ;;
      *)
        echo "date/weekで選択してください"
    esac
  done
}

setDate()
{
  typeset -a isMonth
  while [ "${isMonth}" != y ] && [ "${isMonth}" != N ]
  do
    echo "月を設定しますか? y/N [ y ]"
    read isMonth
    case "${isMonth:=y}" in
      y)
        setMonth hash
        ;;
      N)
        setDay hash
        ;;
      *)
        echo "y/Nで設定してください"
        ;;
    esac
  done
}

setMonth()
{
  typeset -a month
  while [ "${month}" -lt "1" ] || [ "${month}" -gt "12" ]
  do
    echo "月を設定してください 1~12 [ 1 ]"
    read month
    case "${month:=1}" in
      [1-9] | 1[0-2])
        hash[month]="${month}"
        setDay hash
        ;;
      *)
        echo "1から12で設定してください"
        ;;
    esac
  done
}

setDay()
{
  typeset -a isDay
  while [ "${isDay}" != y ] && [ "${isDay}" != N ]
  do
    echo "日を設定しますか? y/N [ y ]"
    read isDay
    case "${isDay:=y}" in
      y)
        typeset -a day
        while [ "${day}" -lt "1" ] || [ "${day}" -gt "31" ]
        do
          echo "日を設定してください 1~31 [ 1 ]"
          read day
          case ${day:=1} in
            [1-9] | [1-2][0-9] | 3[0-1])
              checkValidityOfDay hash day
              ;;
            *)
              echo "1から31で設定してください"
              ;;
          esac
        done
        ;;
      N)
        ;;
      *)
        echo "y/Nで設定してください"
        ;;
    esac
  done
}

checkValidityOfDay()
{
  case "{$day}" in
    "2")
      if [ "{$day}" -gt 29 ]; then
        x=0
      else
        hash[day]="${day}"
      fi
      ;;
    "4" | "6" | "9" | "11")
      if [ "{$day}" -gt 30 ]; then
        x=0
      else
        hash[day]="${day}"
      fi
      ;;
    *)
        hash[day]="${day}"
        ;;
  esac
}

setWeek()
{
  typeset -a week
  while [ "${week}" -lt "1" ] || [ "${week}" -gt "7" ]
  do
    echo "曜日を選択してください\nmon:1/tue:2/web:3/thu:4/fri:5/sat:6/sun:7 [ 1 ]"
    read week
    case "${week:=1}" in 
      [1-7])
        hash[week]="${week}"
        ;;
      *)
        echo "1から7で設定してください"
        ;;
    esac
  done
}

setTime()
{
  old_IFS="${IFS}"
  IFS=:
  typeset -a isTime
  while [ "${isTime}" != ok ]
  do
    echo "時刻を入力してください [ 00:00 ]"
    typeset -a hour
    typeset -a min
    read hour min
    if [ "${hour}" -lt 10 ]; then
      hour="${hour:1}"
    fi
    if [ "${min}" -lt 10 ]; then
      min="${min:1}"
    fi

    case ${hour:=0} in
      [0-9] | 1[0-9] | 2[0-3])
        hash[hour]="${hour}"
        isTime=ok
        ;;
      *)
        echo $hour
        echo "00:00 ~ 23:59の間で入力してください"
        isTime=ng
        ;;
    esac

    if [ "${isTime}" = ok ]; then
      case ${min:=0} in
        [0-9] | [1-5][0-9])
          hash[min]="${min}"
          isTime=ok
          ;;
        *)
          echo $min
          isTime=ng
          echo "00:00 ~ 23:59の間で入力してください"
          ;;
      esac
    fi
  done
  IFS="${old_IFS}"
}
% chmod 755 gen_cron.sh; . ./gen_cron.sh
毎日を指定しますか? y/N [ y ]
N
日付を指定しますか? 曜日を指定しますか? date/week [ date ]
date
月を設定しますか? y/N [ y ]

月を設定してください 1~12 [ 1 ]
13
1から12で設定してください
月を設定してください 1~12 [ 1 ]
12
日を設定しますか? y/N [ y ]
hoge
y/Nで設定してください
日を設定しますか? y/N [ y ]
y
日を設定してください 1~31 [ 1 ]
31
時刻を入力してください [ 00:00 ]
23:60
60
00:00 ~ 23:59の間で入力してください
時刻を入力してください [ 00:00 ]
23:59
設定したいコマンドを入力してください
echo "goodbye this year!"
59 23 31 12 * echo "goodbye this year!"

今日はここまで
明日もなにかしらのScriptを作ろうと思う

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?