Shell - Linux

shellとは

シェルとは、ユーザーが入力するコマンドを実行するプログラムのことです。

シェルによって実行される一連の処理を記述したスクリプトのことです。

bash(Bourne Again Shell) は、数あるシェルのなかの一つです。

bash と sh は基本的なコマンドは同じですが、sh では bash で使えるコマンドや記法が使えない場合があります。

移植性を考えないのであれば、機能が多い bash を使うのがよさそうです。

VScode でシェルスクリプトを各場合、入力補完するには「 Bash IDE 」をインストールすると補完できます。

シェルスクリプト

シェルスクリプトを作成するには、ファイルの拡張子を「 .sh 」にします。

bash を利用する場合は、スクリプトのファイルの最初に次のように記述します。

bash

#!/bin/bash

sh

#!/bin/sh

シェルスクリプトを実行する

「 Hello, World 」と表示するシェルスクリプトを作成します。

test.sh というファイルを作成したら、ファイルのパーミッションを確認します。ファイルの実行権限がなければ、パーミッションを変更します。

パーミッションの変更

chmod 755 test.sh

test.sh

#!/bin/bash
echo "Hello, World"

シェルスクリプトを実行するには、「 source 」を使うか「 . 」を使います。

source test.sh
. test.sh

変数

変数名に指定できるのは、アルファベットと数字のみで先頭に数字、_を指定することができません。

アルファベットは、大文字、小文字どちらでも使えますが、一般的に大文字が環境変数、小文字がシェル変数になります。

=の前後にスペースを入れると正常に動作しません。

変数名の後にコマンドが続くと変数とみなされるため、変数を区切るには、変数を {} で囲みます。

変数を呼び出すには、変数名の前に$をつけます。

test.sh

#!/bin/bash
str="Hello, World"
echo $str

文字列の中で、変数を指定するには、ダブルクォーテーションで文字列をくくります。シングルクォーテーションだとそのまま表示されます。

test.sh

#!/bin/bash
str="bash"
echo "Hello, $str"

コメント

コメントは、コメントの頭に # をつけます。

# は、行頭でも行の途中でも指定できます。

test.sh

#!/bin/bash
str="Hello, World"
# This line is a comment
echo $str

計算

シェルスクリプトの中で、計算するには複数方法があります。bc コマンドを用いた計算は次のように記述します。

test.sh

#!/bin/bash
echo 1+1 | bc

if

構文

if 任意のコマンド; then
    成功時のコマンド
else
    失敗時のコマンド
fi

test.sh

#!/bin/bash
if rm /test.sh; then
  echo "success"
else
  echo "error"
fi

文字列の比較をするには、以下のようにします。

文字列の比較の際、= の前後にはスペースを入れます。

文字列比較で変数が空になる可能性がある場合や空かどうかを判定する場合、変数名を "" でくくっておかないと正しく判定できません。

#!/bin/bash

flag="flase"

if [ "$flag" = "true" ]; then
  echo "true"
else
  echo "false"
fi

値の比較するオプションには、以下の表のものがあります。

オプション 内容 読み方 同じ内容の記号
A -eq B A と B が等しい equal =
A -ne B A と B が等しくない not equal !=
A -gt B A は B より大きい greater than >
A -ge B A が B 以上 greater than or equal >=
A -lt B A が B より小さい less than <
A -le B A が B 以下 less than or equal <=

for文

test.sh

#!/bin/bash
for i in 1 2 3
do
  echo $i
done

シェルスクリプトには、「 += 」がありません。配列に格納されている数字の合計を求めるには、以下のようにします。

#!/bin/bash

arr=(10 20 30 40)

total=0

for i in ${arr[@]}; do
  ((total+=i))
done

echo $total

ループの条件を指定する場合は、以下のようにします。

#!/bin/bash

for((i=0; i<3; i++))
do
  echo $i
done

配列内の値を順番に取り出すには、以下のようにします。

#!/bin/bash

fruits=("apple" "orange" "banana")

for((i=0; i<${#fruits[@]}; i++))
do
  echo ${fruits[$i]}
done

while文

test.sh

#!/bin/bash
i=1
while((i < 4))
do
  echo "hello"
  i=$((i+1))
done

配列

()で囲んで配列にする方法は次のように記述します。

arr=("txt1" "txt2")

# 行を変える場合
arr=(
  "txt1"
  "txt2"
)

インデックスを指定して代入もできます。

arr[0]="txt1"
arr[1]="txt2"

インデックスを指定して表示するには次のようにします。

#!/bin/bash
arr=("txt1" "txt2")
echo ${arr[0]}

配列を for で回す場合は次のようにします。

test.sh

#!/bin/bash
arr=("txt1" "txt2")
for i in ${arr[@]}; do
  echo $i
done

配列の要素数を取得するには、以下のようにします。

#!/bin/bash

fruits=("apple" "orange" "banana")

#  ${#fruits[*]} でも取得できます
echo ${#fruits[@]}

関数

関数を定義するには、function を使いますが、function は省略も可能です。

#!/bin/bash
function hello(){
  echo "hello, world"
}
hello // 呼び出し

引数を渡すには次のようにします。

#!/bin/bash

hello(){
  echo "hello, $1 and $2"
  echo "number of arguments:"$#
}

hello taro hanako

& / && / ; 複数コマンドを続けて実行

「 & / && / ; 」を使って複数のコマンドを実行することができます。また、それぞれの記号によって処理の内容が異なります。

「 & 」は、並列処理で複数のコマンドを実行します。

tree & ls -al

# 3個以上並べて書くこともできます
command1 & command2 & command3

以下のようにすると、処理をバックグランドで実行し、完了していなくてもプロンプトを利用することができます。

node script.js &

「 && 」は、順次処理でコマンドが実行されます。

command1 && command2

上記の場合、「 command1 」がエラーになった場合、「 command2 」は実行されません。

「 ; 」は、「 && 」とほぼ同じですが、処理の成功、失敗に関わらず、続くコマンドを実行することができます。

command1 ; command2