今日もやっていきましょう(自作Script作ってたら日をまたいでた...)
ShellScriptに入門する(1日目)
ShellScriptに入門する(2日目)
ShellScriptに入門する(3日目)
ShellScriptに入門する(4・5・6日目)
関数を勉強し忘れてたので関数から...
関数
関数のスコープ
関数が呼ばれたことによって関数内で$@パラメータの値が変わっている
ただし変数xはグローバル変数であるため、関数内で値が変更されたあとにもその値が反映されている
# !/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は再帰処理によって階乗を求めている
# !/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言語とかで使われてるらしい
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
}
# !/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
# ! /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
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を作ろうと思う