0
1

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

ShellScript メモランダム

Last updated at Posted at 2020-08-28

ドットインストールの学習メモです。


###仮想マシン起動

  • ターミナルでvagrantfileのフォルダまで行って
  • vagrant up 仮想マシン起動
  • vagrant ssh 仮想マシンにログイン.
  • (vagrant status runningを確認)

###shellscriptを書く

  • shellscrpt_lessonsフォルダを作成
  • helloファイルを作る
  • vscodeの右下プレーンテキストをshellscriptに変更
  • コマンドを実行するためのプログラムをかく
  • (#!(シェバン)の後にbashを指定)
  • (which bash バッシュファイルの場所を調べられる)
hello
#!/bin/bash
echo hello
  • ターミナルでパーミッションの変更
  • chmod +x hello
  • ./hello
  • helloが表示される

###文字列を表示してみよう

  • hello の部分を "" か '' で囲む。
  • 1行に複数の命令を書きたい場合は;を入れる
bash
echo "hello"; echo "bye"
  • # comment パウンド記号でコメント化

###変数の使用

  • 変数はラベルのようなもの
  • 変数名は_か英数字。
  • 大文字小文字の区別あり。
  • =の前後に空白の無いように!
hello
name="matasaburou"
echo "hello $name"
echo "hello ${name}さん"
  • 内容を書き換えて欲しく無い場合は readonlyをつける
hello
readonly name="matasaburou"
name="shanshan"
echo "hello ${name}san"
echo "hello $name"

結果  ※shanshanは読み込みに失敗している

terminal
[vagrant@localhost shellscript_lessons]$ ./hello
./hello: line 3: name: 読み込みのみの変数
hello matasaburousan
hello matasaburou

###特殊変数
$1, $2...とコマンドの引数を表す特殊変数を渡すと

hello
echo "hello $1"
terminal
[vagrant@localhost shellscript_lessons]$ ./hello mata
hello mata

$0, $#, $@ or $*で、スクリプトの名前, 引数の数、 全ての引数を表示できる

hello
echo "hello $0"
echo "hello $#"
echo "hello $@"
terminal
[vagrant@localhost shellscript_lessons]$ ./hello mata sasa yoshi
hello ./hello
hello 3
hello mata sasa yoshi

###ユーザーからの入力

hello
read name
echo "hello $name"

ユーザーから1行の入力を受け取りnameに格納してくれる。

terminal
[vagrant@localhost shellscript_lessons]$ ./hello 
newt
hello newt

newtを入力したら組み込まれて出力された。

プロンプトオプション
入力前にテキストの表示させたい場合

hello
read -p "お名前は?:" name
echo "hello $name"
terminal
[vagrant@localhost shellscript_lessons]$ ./hello 
お名前は?:newt
hello newt

複数の入力を受け取る場合

hello
read -p "3つ入力してください:" c1 c2 c3
echo $c1
echo $c2
echo $c3
terminal
[vagrant@localhost shellscript_lessons]$ ./hello 
3つ入力してください:red blue black
red
blue
black

四つの値を入れてしまうと最後の変数が二つ出力される。
二つの値を入力すると3つ目はブランクで表示される。

###配列を使う

hello
colors=(red blue pink)
echo ${colors[0]}
echo ${colors[1]}
echo ${colors[2]}
echo ${colors[@]}
echo ${#colors[@]}

配列の各要素、全ての要素、要素の個数。

terminal
[vagrant@localhost shellscript_lessons]$ ./hello 
red
blue
pink
red blue pink
3

要素の変更

hello
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 + /

terminal
[vagrant@localhost shellscript_lessons]$ ./hello 
red silver pink green orange

###数値計算
値は文字列として処理されてしまうので回避する方法。

hello
echo 5+2

echo `expr 5 + 2`

echo $((5 + 2))

n=5
# (($n=$n+5)) 間違った使い方 
((n=n+5))
echo $n

echo $((10 / 3)) #あまりは返ってこない
terminal
[vagrant@localhost shellscript_lessons]$ ./hello 
5+2
7
7
10
3

###条件分岐 if

hello
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の位置を変えた書き方もある。こっちの方が良さげ? 見やすい・・・

hello
if [ "$name" = "mata" ]; then
	echo "hello ${name}!"
elif [ "$name" = "sasa" ]; then
	echo "hello ${name}!!!!!!!"
else
	echo "you are not allowed"

ちなみに結果は・・・

terminal
[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

###文字列の比較をしてみよう

[[]], (()),など・・・

hello
# [[]] 文字列やファイルの比較
# (()) 数値の比較

read -p "name? " name
if [[ $name = "mata" ]]; then
	echo "hello ${name}!!"
fi
[vagrant@localhost shellscript_lessons]$ ./hello 
name? mata
hello mata!
hello
# = 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
terminal
[vagrant@localhost shellscript_lessons]$ ./hello 
name? 
empty...
----------------------------------
[vagrant@localhost shellscript_lessons]$ ./hello 
name? tom
starts with t...

###ファイルや数値の比較をしてみよう

hello
# -e 存在しているか
# -f ファイルが存在しているか
# -d ディレクトリが存在しているか

if [[ -f $0 ]]; then
	echo "file exists..."
	fi
--------------------------------
if [[ -d $0 ]]; then
	echo "dir exists..."
fi
terminal
[vagrant@localhost shellscript_lessons]$ ./hello 
file exists...
[vagrant@localhost shellscript_lessons]$ ./hello 
なし・・・
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でループ処理をしてみよう

hello
for i in {1..5}; do
echo $i
done

for ((i=1; i<=5; i++)); do
echo $i
done
terminal
#両方とも同じ結果
[vagrant@localhost shellscript_lessons]$ ./hello 
1
2
3
4
5
[vagrant@localhost shellscript_lessons]$ 
hello
colors=(red blue pinkl)
for color in ${colors[@]}; do
	echo $color
done
terminal:terminal
[vagrant@localhost shellscript_lessons]$ ./hello 
red
blue
pinkl
hello
echo $(date)
echo ---------------------

# for item in `date`; do
for item in $(date); do
	echo $item
done
terminal
[vagrant@localhost shellscript_lessons]$ ./hello 
2020年 8月 27日 木曜日 10:54:31 JST
---------------------
2020年
8月
27日
木曜日
10:54:31
JST

###whileを使ってみよう

hello
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
terminal
[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]$ 

###ファイルの処理をしてみよう

terminal
#catでファイル作成
[vagrant@localhost shellscript_lessons]$ cat > color.txt
red
blue
pink
[vagrant@localhost shellscript_lessons]$ cat color.txt 
red
blue
pink
hello
#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の内容に行番号をつけて表示

terminal
[vagrant@localhost shellscript_lessons]$ ./hello
1 red
2 blue
3 pink

テキスト内でファイルを指定せず、helloの内容に行番号をつけて表示

terminal
[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で条件分岐してみよう

hello
read -p "signal color? " color
case "$color" in
	red)
		echo "stop!"
		;;
	blue)
		echo "go!"
		;;
	yellow)
		echo "caution!"
		;;
	*)
		echo "wrong signal"
esac
terminal
[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でユーザーに選択肢を与える。

hello
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
terminal
[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]$ 

###関数を使ってみよう

hello
#関数

# 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 $?
terminal
[vagrant@localhost shellscript_lessons]$ ./hello
hello...
1
hello...mata
0
hello...sasa
1

###変数のスコープを理解しよう

hello

hello() {
	local name="mata"
	echo "hello..."
}

hello
echo $name
#変数はどこでも使えてしまう
#ので、変数のスコープを限定したい場合は
#localを足す
terminal
[vagrant@localhost shellscript_lessons]$ ./hello
hello...
mata
ビフォーアフター
[vagrant@localhost shellscript_lessons]$ ./hello
hello...
      (表示されなくなった!)
[vagrant@localhost shellscript_lessons]$ 

以上で17レッスン終了!
楽しかったのだ1

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?