今日もやっていきましょう
ShellScriptに入門する(1日目)
ShellScriptに入門する(2日目)
ShellScriptに入門する(3日目)
ShellScriptに入門する(4・5・6日目)
変数のスコープ
以下のScriptを作成し、実行する
# !/bin/sh
echo "MYVAR is: $MYVAR"
MYVAR="hello there"
echo "MYVAR is: $MYVAR"
% chmod 755 myvar2.sh; sh myvar2.sh
MYVAR is:
MYVAR is: hello there
想定した動きと同じ...
interactive shellから変数を受け取るためにはexportコマンドを使用する
ShellScript内でMYVARの値がWhat's up?からhello thereに変わっているがinteractive shellには変更後の値は渡されない
% MYVAR="what's up?"
% export MYVAR
% sh myvar2.sh
MYVAR is: What's up?
MYVAR is: hello there
% echo "$MYVAR"
what's up?
また、ShellScript内の変更をinteractive shellに反映させたい場合には .(dot)コマンドが使用できる
export MYVARは必要ない
% MYVAR="what's up?"
% echo "$MYVAR"
what's up?
% . ./myvar2.sh
MYVAR is: what's up?
MYVAR is: hello there
% echo "$MYVAR"
hello there
あと文字列中で変数を展開するときは${VAR}の形でも書けるみたい
これからはこっちの書き方を使っていく
ループ
forループ
下記のようにforの後ろに変数を、inの後ろにループさせる対象を、do done内に実行させたい処理を記述する
また、*はワイルドカードで現在ディレクトリ内のすべてのファイルを意味している
# !/bin/sh
for i in hello 1 * 2 goodbye
do
echo "Looping ... i is set to ${i}"
done
% chmod 755 for2.sh; sh for2.sh
Looping ... i is set to hello
Looping ... i is set to 1
Looping ... i is set to first.sh
Looping ... i is set to for.sh
Looping ... i is set to for2.sh
Looping ... i is set to myvar2.sh
Looping ... i is set to var.sh
Looping ... i is set to var2.sh
Looping ... i is set to 2
Looping ... i is set to goodbye
whileループ
whileの後ろの[]内に条件が記述できる
# !/bin/sh
INPUT_STRING=hallo
while [ "${INPUT_STRING}" != "ciao" ]
do
echo "Please type something in (ciao to quit)"
read INPUT_STRING
echo "You typed: ${INPUT_STRING}"
done
% chmod 755 while.sh; sh while.sh
Please type something in (ciao to quit)
hallo
You typed: hallo
Please type something in (ciao to quit)
ciao
You typed: ciao
:は常にtrueと評価されるため無限ループとなる
# !/bin/sh
while :
do
echo "Please type something in (^C to quit)"
read INPUT_STRING
echo "You typed: ${INPUT_STRING}"
done
Please type something in (^C to quit)
hallo
You typed: hallo
Please type something in (^C to quit)
ciao
You typed: ciao
Please type something in (^C to quit)
^C
これはファイルを1行ずつ読み取ってcaseで分岐している
# !/bin/sh
while read f
do
case $f in
hello) echo "English" ;;
howdy) echo "American" ;;
gday) echo "Australian" ;;
bonjour) echo "French" ;;
"guten tag") echo "German" ;;
konnichiwa) echo "Japanese" ;;
*) echo "Unknown Language: $f" ;;
esac
done < myfile
% echo "hello" > myfile
% echo "konnichiwa" >> myfile
% echo "hoge" >> myfile
% chmod 755 while3.sh; sh while3.sh
English
Japanese
Unknown Language: hoge
Test
testはほぼすべてのShellScriptに使われているけどほとんど見当たらない
その理由が[がtestのシンボリックリンクだからであり、すでに whileループ; while.shでも使用していた
そのため if SPACE [ SPACE "$foo" SPACE = SPACE "bar" SPACE ]のように[の前後にスペースを入れる必要がある
めちゃくちゃオプションがあるから、最初のうちはひたすらググって書くことになりそう
# !/bin/sh
if [ "${X}" -lt "0" ] # -lt: lesser than
then
echo "X is less than zero"
fi
if [ "${X}" -gt "0" ]; then # -gt: greater than
echo "X is more than zero"
fi
[ "${X}" -le "0" ] && echo "X is less than or equal to zero" # -le: lesser or equal
[ "${X}" -ge "0" ] && echo "X is more than or equal to zero" # -ge: greater or equal
[ "${X}" = 0 ] && echo "X is the string or number \"0\""
[ "${X}" = "hello" ] && echo "X matches the string \"hello\""
[ "${X}" != "hello" ] && echo "X is not the stirng \"hello\""
[ -n "${X}" ] && echo "X is of nonzero length" # -n: True if string is not empty.
[ -f "${X}" ] && echo "X is the path of a real file" || echo "No such file ${X}" # True if file exists and is a regular file.
[ -x "${X}" ] && echo "X is the path of an excutable file" # True if the file is executable by you.
[ "${X}" -nt "/etc/passwd" ] && echo "X is a file which is newer than /etc/passwd" # True if file1 is newer than file2
% X="hello"
% export X
% chmod 755 test.sh; sh test.sh
test.sh: 2: [: Illegal number: hello
test.sh: 6: [: Illegal number: hello
test.sh: 9: [: Illegal number: hello
test.sh: 10: [: Illegal number: hello
X matches the string "hello"
X is of nonzero length
No such file hello
Case
case ~ esacの中に記述していく
*)で当てはまらないものすべてをキャッチできる (default:みたいな認識)
多少書き方は違うけど(":"が")"になっているとか)、割とすんなり理解できた
# !/bin/sh
echo "Bitte sprich mit mir ..."
while :
do
read INPUT_STRING
case $INPUT_STRING in
hallo)
echo "Hallo!"
;;
ciao)
echo "Ciao!"
break
;;
*)
echo "Entschuldigung, ich verstehe nicht"
;;
esac
done
echo "Das war's Leute!"
% chmod 755 talk.sh; sh talk.sh
Bitte sprich mit mir ...
hallo
Hallo!
guten morgen
Entschuldigung, ich verstehe nicht
ciao
Ciao!
Das war's Leute!
変数(Part2)
$#がパラメータの数で、$0はファイル名、$1 ... $9はそれぞれのパラメータ、 $@はすべてのパラメータ
# !/bin/sh
echo "I was called with ${#} parameters"
echo "My name is ${0}"
echo "My first parameter is ${1}"
echo "My second parameter is ${2}"
echo "All parameters are $@"
% chmod 755 var3.sh; sh var3.sh
I was called with 0 parameters
My name is var3.sh
My first parameter is
My second parameter is
All parameters are
% sh var3.sh hello ShellScript
I was called with 2 parameters
My name is var3.sh
My first parameter is hello
My second parameter is ShellScript
All parameters are hello ShellScript
9個以上のパラメータを取り扱いたいときはループの中でshiftを用いて引数を1つずつずらしていく
# !/bin/sh
while [ "${#}" -gt "0" ]
do
echo "\$1 is $1"
shift
done
% chmod 755 var4.sh; sh var4.sh hoge fuga piyo
$1 is hoge
$1 is fuga
$1 is piyo
IFS(Internal Field Separator)は区切り文字が設定をすることができる
bashやzshなどの多くのシェルでスペースや改行文字などがデフォルトで設定されている
複数のデフォルトが設定されているからバックアップするときはold_IFS=$IFSじゃなくてold_IFS="$IFS"とするのが大事
old_IFS="${IFS}"
IFS="${old_IFS}"
# !/bin/sh
old_IFS="${IFS}"
IFS=:
echo "Please input some data separated by colons ..."
read x y z
IFS="${old_IFS}"
echo "x is ${x} y is ${y} z is ${z}"
% chmod 755 ifs.sh; sh ifs.sh
Please input some data separated by colons ...
hello:kshiva:what a day!
x is hello y is kshiva z is what a day!
変数(Part3)
デフォルト値
${VAR:-DEFAULT}は変数VARに値がセットされていない場合にDEFAULTが展開される
VARにDEFAULTが代入されるわけではない
# !/bin/sh
echo "What is your name [ `whoami` ]"
read myname
echo "Your name is : ${myname:-`whoami`}"
echo "\$myname is ${myname}"
% sh name.sh
What is your name [ kshiva ]
Your name is : kshiva
$myname is
% sh name.sh
hoge
Your name is : hoge
$myname is hoge
${VAR:=DEFAULT}は変数VARに値がセットされていない場合にDEFAULTが展開され、VARにDEFAULTが代入される
# !/bin/sh
echo "What is your name [ `whoami` ]"
read myname
echo "Your name is : ${myname:=`whoami`}"
echo "\$myname is ${myname}"
% chmod 755 name2.sh; sh name2.sh
What is your name [ kshiva ]
Your name is : kshiva
$myname is kshiva
% sh name2.sh
What is your name [ kshiva ]
fuga
Your name is : fuga
$myname is fuga
今日はここまで
とりあえず変数からループ処理、testコマンド、caseコマンドの書き方がわかったので、明日から簡単な自作Scriptを書いていく
参考ページ:
https://www.atmarkit.co.jp/ait/articles/1807/05/news041.html#sample3
http://linuxcommand.org/lc3_man_pages/testh.html