Shellスクリプトの基礎から応用まで:実践ガイド

シェルスクリプトの作成と実行方法

シェルスクリプトは、LinuxやUnix系OSでコマンドを自動化するために使用されるテキストファイルです。まず、script.shという名前のファイルを作成し、エディタ(例: vim)で編集します。スクリプトの先頭にはインタプリタのパスを指定します。

#!/bin/bash
# または
#!/bin/sh
# /bin/shは多くのシステムでdashを指している

スクリプトに実行権限を与えるには、以下のコマンドを使用します。

chmod u+x script.sh

実行方法は主に3つあります。

  • ./script.sh:カレントディレクトリ内のスクリプトを実行します。実行権限が必要です。
  • sh script.sh:明示的にshインタプリタを呼び出して実行します。権限がなくても実行可能です。
  • source script.sh または . script.sh:現在のシェル環境内でスクリプトを読み込み、変数や関数の変更が継続します。

変数の扱い方

変数は代入時にスペースを入れず、参照時は$記号を使います。

username="takaba"
count=100
greeting="Hello, World!"

変数の展開は、ダブルクォート内では有効ですが、シングルクォート内では無視されます。

echo "こんにちは、$username"  # 出力: こんにちは、takaba
echo 'こんにちは、$username'  # 出力: こんにちは、$username

文字列の長さを取得したり、部分文字列を抽出することもできます。

text="shell scripting"
echo ${#text}           # 長さ: 15
echo ${text:0:5}         # 先頭5文字: shell

不要になった変数はunsetで削除できます。

unset username

環境変数の永続化

カスタムスクリプトをどこからでも実行可能にするには、そのパスをPATH環境変数に追加します。

export PATH="/home/user/scripts:$PATH"

この設定はセッション終了後には消えてしまうため、永続化するには~/.bashrcや~/.profileに記述し、source ~/.bashrcで反映させます。

引数の受け渡し

スクリプトに引数を渡すことができます。各位置の引数は$1、$2のように参照します。

echo "スクリプト名: $0"
echo "第1引数: $1"
echo "全引数(結合): $*"
echo "全引数(個別): $@"
echo "引数の数: $#"
echo "直前のコマンドの終了コード: $?"
echo "プロセスID: $$"

算術演算

基本的な計算にはexprコマンドを使います。演算子の前後にスペースが必要です。

expr 5 + 3     # 加算
expr 10 - 4    # 減算
expr 6 \* 7    # 乗算(アスタリスクはエスケープ)
expr 20 / 4    # 除算
expr 10 % 3    # 剰余

複雑な式では括弧を使う場合、エスケープが必要です。

expr \( 2 + 3 \) \* 4  # 結果: 20

変数への代入にはコマンド置換を使います。

result=$(expr 8 \* 5)
echo $result  # 出力: 40

ユーザーとの対話:readコマンド

readコマンドを使って、ユーザーの入力を取得できます。

read -p "名前を入力してください: " name
echo "こんにちは、$nameさん"

オプションで挙動を制御できます。

  • -t 10:10秒でタイムアウト
  • -n 3:最大3文字まで入力
read -t 10 -n 3 -p "3文字以内で入力: " input

条件判定

数値比較には以下のような演算子を使います。

  • -eq:等しい
  • -ne:等しくない
  • -lt:より小さい
  • -gt:より大きい
if [ "$a" -eq "$b" ]; then
    echo "等しい"
fi

文字列の比較では=や!=を使います。

if [ "$str1" = "$str2" ]; then
    echo "文字列は同じ"
fi

-zは空文字列かどうか、-nは非空かどうかを判定します。

論理演算と分岐

-a(AND)、-o(OR)で複数条件を組み合わせられます。

if [ "$age" -ge 18 -a "$has_license" = "yes" ]; then
    echo "運転できます"
fi

if-elif-else構文で複数の条件分岐が可能です。

繰り返し処理

forループはリストや範囲に対して反復処理を行います。

for i in 1 2 3 4 5; do
    echo "数値: $i"
done

seqコマンドやC言語風の二重括弧構文も利用できます。

for i in $(seq 1 5); do
    echo $i
done

for ((j=1; j<=5; j++)); do
    echo $j
done

whileループは条件が真の間、処理を繰り返します。

counter=1
while [ $counter -le 5 ]; do
    echo $counter
    counter=$((counter + 1))
done

untilループは条件が偽である限り、処理を続けます。

num=1
until [ $num -gt 5 ]; do
    echo $num
    num=$((num + 1))
done

case文による分岐

複数の値に基づいて処理を分岐させる場合に便利です。

read -p "数字を入力: " num
case $num in
    1) echo "一" ;;
    2) echo "二" ;;
    *) echo "その他" ;;
esac

関数の定義と利用

繰り返し使う処理は関数として定義できます。

greet() {
    local user=$1
    echo "こんにちは、$userさん!"
}
greet "Yamada"

別のスクリプト内で定義された関数や変数を利用するにはsourceを使います。

# config.sh
username="admin"
role="system"

# main.sh
source ./config.sh
echo "ユーザー: $username, 権限: $role"

入出力のリダイレクト

標準出力をファイルに書き込むには>(上書き)または>>(追記)を使います。

ls > files.txt
date >> log.txt

標準入力をファイルから読み込むには<を使います。

sort < data.txt

ファイルディスクリプタ(0: 標準入力, 1: 標準出力, 2: エラー出力)を使って、出力先を分けることもできます。

command > output.log 2> error.log

出力を破棄したい場合は/dev/nullにリダイレクトします。

ls > /dev/null

タグ: Shellスクリプト bash コマンドライン 自動化 linux

9月19日 23:10 投稿