ドットインストールの学習メモです。
###仮想マシン起動
- ターミナルでvagrantfileのフォルダまで行って
-
vagrant up
仮想マシン起動 -
vagrant ssh
仮想マシンにログイン. - (
vagrant status
runningを確認)
###shellscriptを書く
- shellscrpt_lessonsフォルダを作成
- helloファイルを作る
- vscodeの右下プレーンテキストをshellscriptに変更
- コマンドを実行するためのプログラムをかく
- (
#!
(シェバン)の後にbashを指定) - (
which bash
バッシュファイルの場所を調べられる)
#!/bin/bash
echo hello
- ターミナルでパーミッションの変更
chmod +x hello
./hello
- helloが表示される
###文字列を表示してみよう
- hello の部分を
""
か''
で囲む。 - 1行に複数の命令を書きたい場合は
;
を入れる
echo "hello"; echo "bye"
-
# comment
パウンド記号でコメント化
###変数の使用
- 変数はラベルのようなもの
- 変数名は_か英数字。
- 大文字小文字の区別あり。
- =の前後に空白の無いように!
name="matasaburou"
echo "hello $name"
echo "hello ${name}さん"
- 内容を書き換えて欲しく無い場合は readonlyをつける
readonly name="matasaburou"
name="shanshan"
echo "hello ${name}san"
echo "hello $name"
結果 ※shanshanは読み込みに失敗している
[vagrant@localhost shellscript_lessons]$ ./hello
./hello: line 3: name: 読み込みのみの変数
hello matasaburousan
hello matasaburou
###特殊変数
$1
, $2
...とコマンドの引数を表す特殊変数を渡すと
echo "hello $1"
[vagrant@localhost shellscript_lessons]$ ./hello mata
hello mata
$0, $#, $@ or $*
で、スクリプトの名前, 引数の数、 全ての引数を表示できる
echo "hello $0"
echo "hello $#"
echo "hello $@"
[vagrant@localhost shellscript_lessons]$ ./hello mata sasa yoshi
hello ./hello
hello 3
hello mata sasa yoshi
###ユーザーからの入力
read name
echo "hello $name"
ユーザーから1行の入力を受け取りname
に格納してくれる。
[vagrant@localhost shellscript_lessons]$ ./hello
newt
hello newt
newtを入力したら組み込まれて出力された。
プロンプトオプション
入力前にテキストの表示させたい場合
read -p "お名前は?:" name
echo "hello $name"
[vagrant@localhost shellscript_lessons]$ ./hello
お名前は?:newt
hello newt
複数の入力を受け取る場合
read -p "3つ入力してください:" c1 c2 c3
echo $c1
echo $c2
echo $c3
[vagrant@localhost shellscript_lessons]$ ./hello
3つ入力してください:red blue black
red
blue
black
四つの値を入れてしまうと最後の変数が二つ出力される。
二つの値を入力すると3つ目はブランクで表示される。
###配列を使う
colors=(red blue pink)
echo ${colors[0]}
echo ${colors[1]}
echo ${colors[2]}
echo ${colors[@]}
echo ${#colors[@]}
配列の各要素、全ての要素、要素の個数。
[vagrant@localhost shellscript_lessons]$ ./hello
red
blue
pink
red blue pink
3
要素の変更
colors=(red blue pink)
# echo ${colors[0]}
# echo ${colors[1]}
# echo ${colors[2]}
# echo ${colors[@]}
# echo ${#colors[@]}
colors[1]=silver
colors+=(green orange)
echo ${colors[@]}
コメントアウトするにはcommand + /
[vagrant@localhost shellscript_lessons]$ ./hello
red silver pink green orange
###数値計算
値は文字列として処理されてしまうので回避する方法。
echo 5+2
echo `expr 5 + 2`
echo $((5 + 2))
n=5
# (($n=$n+5)) 間違った使い方
((n=n+5))
echo $n
echo $((10 / 3)) #あまりは返ってこない
[vagrant@localhost shellscript_lessons]$ ./hello
5+2
7
7
10
3
###条件分岐 if
read -p "name? " name
# if test "$name" = "mata"
# if ["$name" = "mata"] []の間に空白がないとエラー
if [ "$name" = "mata" ]
then
echo "hello ${name}!"
elif [ "$name" = "sasa" ]
then
echo "hello ${name}!!!!!!!"
else
echo "you are not allowed"
fi
thenの位置を変えた書き方もある。こっちの方が良さげ? 見やすい・・・
if [ "$name" = "mata" ]; then
echo "hello ${name}!"
elif [ "$name" = "sasa" ]; then
echo "hello ${name}!!!!!!!"
else
echo "you are not allowed"
ちなみに結果は・・・
[vagrant@localhost shellscript_lessons]$ ./hello
name? sasa
hello sasa!!!!!!!
[vagrant@localhost shellscript_lessons]$ ./hello
name? mata
hello mata!
[vagrant@localhost shellscript_lessons]$ ./hello
name? gsgsg
you are not allowed
###文字列の比較をしてみよう
[[]], (()),など・・・
# [[]] 文字列やファイルの比較
# (()) 数値の比較
read -p "name? " name
if [[ $name = "mata" ]]; then
echo "hello ${name}!!"
fi
[vagrant@localhost shellscript_lessons]$ ./hello
name? mata
hello mata!
# = or == 文字列が等しい
# != 等しくない
# -z 文字列の長さが0かどうか
# =~ 正規表現
read -p "name? " name
if [[ -z $name ]]; then
echo "empty..."
fi
---------------------------------
read -p "name? " name
if [[ $name =~ ^t ]]; then #tから始まる
echo "starts with t..."
fi
[vagrant@localhost shellscript_lessons]$ ./hello
name?
empty...
----------------------------------
[vagrant@localhost shellscript_lessons]$ ./hello
name? tom
starts with t...
###ファイルや数値の比較をしてみよう
# -e 存在しているか
# -f ファイルが存在しているか
# -d ディレクトリが存在しているか
if [[ -f $0 ]]; then
echo "file exists..."
fi
--------------------------------
if [[ -d $0 ]]; then
echo "dir exists..."
fi
[vagrant@localhost shellscript_lessons]$ ./hello
file exists...
[vagrant@localhost shellscript_lessons]$ ./hello
なし・・・
# == 等しい
# != 等しくない
# > >= より大きい、以上
# < <= より小さい、以下
# && and
# || or
# ! not
read -p "number? " n
if (( n > 10 )); then
echo "bigger than 10 !!"
fi
[vagrant@localhost shellscript_lessons]$ ./hello
number? 1
[vagrant@localhost shellscript_lessons]$ ./hello
number? 11
bigger than 10 !!
###forでループ処理をしてみよう
for i in {1..5}; do
echo $i
done
for ((i=1; i<=5; i++)); do
echo $i
done
#両方とも同じ結果
[vagrant@localhost shellscript_lessons]$ ./hello
1
2
3
4
5
[vagrant@localhost shellscript_lessons]$
colors=(red blue pinkl)
for color in ${colors[@]}; do
echo $color
done
terminal:terminal
[vagrant@localhost shellscript_lessons]$ ./hello
red
blue
pinkl
echo $(date)
echo ---------------------
# for item in `date`; do
for item in $(date); do
echo $item
done
[vagrant@localhost shellscript_lessons]$ ./hello
2020年 8月 27日 木曜日 10:54:31 JST
---------------------
2020年
8月
27日
木曜日
10:54:31
JST
###whileを使ってみよう
i=0
while ((i < 10)); do
((i++))
echo $i
done
echo ----------------
i=0
while ((i < 10)); do
((i++))
if ((i == 4)); then
continue
fi
if ((i == 8)); then
break
fi
echo $i
done
while :
do
read -p "command? " cmd
if [[ $cmd == "quit" ]]; then
break
else
echo "$cmd"
fi
done
[vagrant@localhost shellscript_lessons]$ ./hello
1
2
3
4
5
6
7
8
9
10
----------------
1
2
3
5
6
7
command? kaka
kaka
command? sasa
sasa
command? quit
[vagrant@localhost shellscript_lessons]$
###ファイルの処理をしてみよう
#catでファイル作成
[vagrant@localhost shellscript_lessons]$ cat > color.txt
red
blue
pink
[vagrant@localhost shellscript_lessons]$ cat color.txt
red
blue
pink
#color.txtの内容に行番号をつけて表示
i=1
while read line; do
echo $i "$line"
((i++))
done < color.txt
echo --------------------
#テキスト内でファイルを指定せず、helloの内容に行番号をつけて表示
i=1
while read line; do
echo $i "$line"
((i++))
# done < color.txt テキスト内でファイル名をしてしたくない
done
(ちょっと分割)
color.txtの内容に行番号をつけて表示
[vagrant@localhost shellscript_lessons]$ ./hello
1 red
2 blue
3 pink
テキスト内でファイルを指定せず、helloの内容に行番号をつけて表示
[vagrant@localhost shellscript_lessons]$ cat hello | ./hello
1 #!/bin/bash
2
3 i=1
4 while read line; do
5 echo $i "$line"
6 ((i++))
7 done < color.txt
8 echo --------------------
9
10 i=1
11 while read line; do
12 echo $i "$line"
13 ((i++))
14 # done < color.txt
15 done
16
17
18
ちなみに
なんかごちゃごちゃしてわかりにくいので、
color.textバージョンで両方やってみると
[vagrant@localhost shellscript_lessons]$ cat color.txt | ./hello
1 red
2 blue
3 pink
--------------------
1 red
2 blue
3 pink
同じ結果になる。のでokってことで。
よーするに、今のhelloは他のファイルから行を読み取って、
行番号を足すシェルスクリプトになったってこと。
なんて姿になったんだ、お前・・・。
cat color.txt | ./hello
catでファイルを指定して内容を表示
そんで ./helloで行番号追加、
したものを表示してくれるというパイプを使ったコマンドライン。
###caseで条件分岐してみよう
read -p "signal color? " color
case "$color" in
red)
echo "stop!"
;;
blue)
echo "go!"
;;
yellow)
echo "caution!"
;;
*)
echo "wrong signal"
esac
[vagrant@localhost shellscript_lessons]$ ./hello
signal color? red
stop!
[vagrant@localhost shellscript_lessons]$ ./hello
signal color? yellow
caution!
[vagrant@localhost shellscript_lessons]$ ./hello
signal color? blue
go!
[vagrant@localhost shellscript_lessons]$ ./hello
signal color? pink
wrong signal
ちなみに
blue|green) echo "go!"
とすると greenでもちゃんとgo!と表示してくれる。
*ワイルドカードや部分一致なども使える。
selectでユーザーに選択肢を与える。
select color in red blue yellow green; do
case "$color" in
red)
echo "stop!"
;;
blue|green)
echo "go!"
;;
yellow)
echo "caution!"
;;
*)
echo "wrong signal"
break #selectはループ処理なのでbreakが必要、今回はここ
esac
done
[vagrant@localhost shellscript_lessons]$ ./hello
1) red
2) blue
3) yellow
4) green
#? 1
stop!
#? 2
go!
#? 3
caution!
#? 4
go!
#? 5
wrong signal
[vagrant@localhost shellscript_lessons]$
###関数を使ってみよう
#関数
# function hello() { これを省略すると↓
hello() {
echo "hello...$1"
if [[ $1 == "mata" ]]; then
return 0 #終了ステータスは0
else
return 1 #終了ステータスは1
#終了ステータスは0から255の間で指定できる。0は正常終了、それ以外(大抵1)じゃ以上終了。
#returnをつけないと実行したコマンドのステータスがそのまま関数雨の終了ステータスになってしまう。
#残るってことね。
fi
}
#関数の実行
#echo $?で直前の実行結果の終了ステータスを調べる。
hello
echo $?
hello mata ;echo $?
hello sasa ;echo $?
[vagrant@localhost shellscript_lessons]$ ./hello
hello...
1
hello...mata
0
hello...sasa
1
###変数のスコープを理解しよう
hello() {
local name="mata"
echo "hello..."
}
hello
echo $name
#変数はどこでも使えてしまう
#ので、変数のスコープを限定したい場合は
#localを足す
[vagrant@localhost shellscript_lessons]$ ./hello
hello...
mata
ビフォーアフター
[vagrant@localhost shellscript_lessons]$ ./hello
hello...
(表示されなくなった!)
[vagrant@localhost shellscript_lessons]$
以上で17レッスン終了!
楽しかったのだ1