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に入門する(2日目)

1
Last updated at Posted at 2019-08-10

今日もやっていきましょう

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

変数のスコープ

以下のScriptを作成し、実行する

myvar2.sh
# !/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内に実行させたい処理を記述する
また、*はワイルドカードで現在ディレクトリ内のすべてのファイルを意味している

for2.sh
# !/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の後ろの[]内に条件が記述できる

while.sh
# !/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と評価されるため無限ループとなる

while2.sh
# !/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で分岐している

while3.sh
# !/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 ]のように[の前後にスペースを入れる必要がある
めちゃくちゃオプションがあるから、最初のうちはひたすらググって書くことになりそう

test.sh
# !/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:みたいな認識)
多少書き方は違うけど(":"が")"になっているとか)、割とすんなり理解できた

talk.sh
# !/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はそれぞれのパラメータ、 $@はすべてのパラメータ

var3.sh
# !/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つずつずらしていく

var4.sh
# !/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}"
ifs.sh
# !/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が代入されるわけではない

name.sh
# !/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が代入される

name2.sh
# !/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

1
0
2

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?