Bash での Linux シェルスクリプトの簡単なガイド

Linuxシェルスクリプトについてもっと学びたいと思ったことはありませんか?Unix系オペレーティングシステムに比較的新しく、基本的なシェルプログラミングのスキルを伸ばしたいですか?この初心者向けチュートリアルでは、Bashを使ったLinuxシェルスクリプトの基本、スクリプトの作成と実行、文字列とループの操作について説明します。

シェルスクリプトは一般的な管理タスクの自動化に使用されます

オペレーティングシステムに関係なく、シェルスクリプトは繰り返しの多い管理タスクを自動化するために使われます。例えば、Windowsではファイルエクスプローラーを使ってファイル名を変更できますが、多くのファイルをリネームする場合、グラフィカルシェルで行うのは時間のかかる作業です。PowerShellを使えば、タスクを自動化して確実に繰り返すことができます。

広告

Linux系オペレーティングシステムでは、Bashや他のシェルが、ファイル操作やシステム設定の変更など、通常なら一つ一つのコマンドを入力して行うようなタスクの自動化に使われます。

Bashシェルスクリプトを学ぶために必要なもの

Bashスクリプトを書いて実行するには、以下の3つだけが必要です。

  • プレーン テキスト エディタ、例えば、Notepad、Text Editor、TextEdit、vi、emacs、または Visual Studio Code。
  • terminal emulator, an application that comes preinstalled with most operating systems and is often called Terminal, Console, or Command Prompt.
  • Bash それ自体。

ターミナル エミュレータは、コマンドを入力して Enter キーまたは Return キーを押して実行する場所です。Bash に関しては、事前インストールされているかどうかはプラットフォームによります。

  • macOSでは、Bash が事前にインストールされています。より新しいバージョンでは、デフォルトのシェルが Z シェル(zsh)になっていますが、問題ありません。Bash がインストールされていれば、zsh からも Bash スクリプトを実行できます。
  • Linux ディストリビューションでは、一般的に Bash がインストールされています。(システムに /bin/bash ファイルが含まれているかどうかを確認することで確認できます。)Android は Bash が同梱されていない特殊なケースです。Android に Bash を取得するための手順がありますが、この記事では取り扱いません。
  • WindowsはBashがバンドルされていません。PowerShellはWindowsのデフォルトのコマンドラインシェルです。Bashを実行するには、Windows Subsystem for Linux(WSL)の下にLinuxディストリビューションをインストールする必要があります。

Bashバージョンを見つけるには、bash –versionコマンドを実行します。さらに古いBashバージョンでも多くの機能が提供されますが、Bash 3と4では特定の基本コマンドに対するショートハンド表記が導入されています。これらのバージョンのBashが必要なコマンドの場合は、以下に記載されています。

広告

シェルとは何ですか?

コンピューティングの世界では、シェルは基礎となるOSへのインタフェースとして機能するプログラムです。シェルは、Windowsシェルのようなグラフィカルユーザインターフェース(GUI)である場合もあります。

シェルスクリプト言語

しかしながら、一般的に人々は用語を、特にコマンドラインインターフェース(CLI)を指すために使用します — キーボードだけを使って対話するテキストの行から成るインタフェースです。*nixオペレーティングシステム向けのシェルスクリプト言語の例をいくつか示します:

ここでは、バッシュシェルに焦点を当てます。これは、ほとんどのLinuxディストリビューションやmacOSにプリインストールされている人気のある無料のUnixシェルです。

シェルスクリプトとは何ですか?

シェルには独自のプログラミング言語があります。この言語を使用してシェルに命令を送り、それを実行させます。これらのコマンドを直接シェルに入力することもできますし、それらをファイルに保存して実行することもできます — それが スクリプト です。コマンドを記述する構文は、どちらの場合も同じです。

広告

この記事では、このファイルを作成するためのシェルスクリプトの基礎をカバーします。

基本的なシェルスクリプト

基本的なシェルスクリプトから始めましょう。簡単なスクリプトを書くために、Linuxでいくつかの簡単なシェルスクリプトコマンドを学びます:

  1. テキストエディターで新しい空のテキストファイルを作成します。
  2. 最初の行に#!/bin/bashを記述します。
  3. その下にコマンドを入力します。
  4. ファイルを保存します。拡張子は可能であれば“.sh”または何もありません。

この#!/bin/bash行は“shebang”と呼ばれます。これはこのスクリプトをBashで実行する必要があることをシェルに伝え、スクリプト内で最初の行である必要があります。異なるシェルに切り替えても、スクリプトは引き続きBashで実行されます。

このプロセスを自分で試すには、ホームディレクトリに‘hello_world’という名前のファイルを作成します:

#!/bin/bash
echo "hello world"

以上で、Bashスクリプトを作成しました!

Our “hello world” script is just a simple text file

実行する前に、おそらくファイルのアクセス権を変更する必要があります。

chmodを使用してシェルスクリプトの実行権限を設定する

hello_world‘ファイルの権限を変更するには、端末エミュレーターで特定のコマンドを実行します。これにより、ファイルの所有者にファイルを実行する権限が与えられます。

chmod u+x 'hello_world'
Running our script without vs. with the “execute” permission

シェルスクリプトを実行したい場合は、次のセクションにスキップできます。気になる方のために、chmod コマンド について、chmod は「change mode」の略語で、Unix でファイルの「モード」(またはアクセス権限)を変更するために使用されます。Unix ライクなオペレーティングシステムでは、3つのユーザークラスに対してファイルの権限を設定できます:

  • ファイルの所有者(chmod で表されるu)。
  • ファイルを所有するグループ(g)。
  • その他(o)。

また、chmod コマンドを使用すると、a を使用してこれらすべてを参照することもできます。

各ファイルには 3 種類の権限(または「モード」)があります:

  • 読み取り(r
  • 書き込み(w
  • 実行(x

そして、権限を追加する(+)または削除する(-)こともできます。

chmod の最初のパラメータは、これらの 3 つの組み合わせです — 所有者最初、アクション次、モード最後。以下はいくつかのコマンド例です:

  • chmod gu+rw 'hello_world' は所有者と所有するグループに読み取りおよび書き込み権限を追加します。
  • chmod a-x 'hello_world' はすべての実行可能権限を削除します。
  • chmod u+rwx 'hello_world' 'hello_world_2' は、所有者に「hello_world」と「hello_world_2」ファイルの読み込み、書き込み、実行の許可を与えます。

ここではchmodコマンドの非常に基本的な部分しかカバーしていません。これらのモードを定義するもっと複雑で冗長ではない方法(「数値表記」)や、ファイルにどの権限があるかを確認するための別のコマンド(ls -l)もあります。これらのトピックには触れません。

シェルスクリプトの実行

最初のスクリプトを実行する時間です。一般的には、スクリプトを実行するには、単にそのパスを端末エミュレータに入力してエンターキーを押します。

./hello_world

相対パスまたは絶対パスを使用できます。相対パスを使用する場合は、常にコマンドの先頭に./を使ってください:これにより、端末に現在のフォルダ('.'で表される)を見るよう指示され、PATH環境変数で定義されたディレクトリではなくなります。

Just typing the script name doesn’t work, but running its relative or absolute paths does

スクリプトにコメントを使用してスクリプトを注釈する

Bashスクリプトの1行に#以降のすべてはコメントと見なされます。これは、複雑な行が何をするかを伝えたり、スクリプトの大きな部分が何をするかを説明するのに役立ちます。

例:

#!/bin/bash

#
# This shell script prints "hello world".
#

echo "hello world" # This line prints "hello world".

変数への紹介

スクリプトを書く際、変数を定義することは役立つことがあります。Bashでは、変数名と値をイコールで区切って入力することで行います:VARIABLENAME='VALUE'

イコール記号の隣にスペースを入れないでください — Bashはプロセスを実行したいと思うと解釈してしまいます。

値を別のものとして解釈しないようにするために、値をシングルクォートで囲んでください。Bashでは、変数には型がなく — 基本的にすべて文字列です。Bashプログラムによって、文字列を数値など異なる型として解釈するかどうかが決まります。

変数の値を参照するには、ドル記号の後に変数名を使ってください:$VARIABLENAME

これを実践してみるには、スクリプトを以下のように変更できます:

#!/bin/bash
HELLO="hello variable world"
echo $HELLO # should print "hello variable world"

引数の受け取り

コマンドを入力する際に書く個々の単語は 引数と呼ばれます。私たちのchmod u+x 'hello_world'の例では、chmodu+x、そして 'hello_world'が三つの別々の引数です。chmodはコマンド名で、u+xhello_worldパラメータと呼ばれる — コマンドに追加情報を提供する引数です。

スクリプト内では、これらの引数にアクセスできます。ローカル変数との競合を避けるために、これらの変数は番号を使って名前をつけます — $0はコマンド名を指し、$1はその次の引数を示し、$2はその次の引数を表し、これ以降続きます。

Let’s try this out:

#!/bin/bash
HELLO="hello $1 world"
echo $HELLO

Now, run this script with these parameters:

./hello_world bash script

The output should be hello bash world, with the first parameter used and the second ignored.

If you wanted bash script to be seen as one parameter, you would need to put it in quotes: 

./hello_world 'bash script'
Words separated by a space are considered as several arguments, except when in quotes

条件に応じてコードを実行するためにif文を使用する

スクリプト内でプログラマーが行いたいと考える主要なことの一つは、特定の条件が満たされた場合にのみコードを実行することです。それに対してBashにはif文があります:

NUM=$RANDOM
if (( $NUM % 2 )) # if CONDITION
then
    echo "$NUM is odd"
fi # this is how you end an if statement

ヒント:ここから先、これらの例はより大きなスクリプトの一部であると想定され、冒頭に#!/bin/bashを省略しています。ただし、スクリプトの最初の行としてそれを忘れないでください!

elseif文の内部で使用して、条件が満たされない場合の処理を指定したり、elif(“else if”の略)文を使用して、最初の条件が満たされなかった場合の別の条件を指定することもできます:

NUM=$RANDOM
if [ $NUM -eq 12 ]
then
    echo "$NUM is my favorite number"
elif (( $NUM % 2 ))
then
    echo "$NUM is odd"
else
    echo "$NUM is even"fi

fi‘はif文を閉じるために使用されます。

ヒント:条件自体の書き方がわからない場合は、test、単一の角括弧([])、および二重括弧((()))の表記を調べてみてください。

The output of our script depends on the value of a random variable

forループを使用して一連のコマンドを繰り返す

条件付きでコードを実行する方法をカバーしたので、ある条件が満たされる限り特定の回数コードを実行する方法を見てみましょう。

そのようなタスクには、forループが最適です — 特にその「3つの式構文」です。その考え方は、ループ固有の変数を割り当て、それを徐々に変更して特定の条件が満たされるまで変更することです。構造は次のようになります:

for (( ASSIGNMENT_EXPRESSION ; CONDITION_EXPRESSION ; UPDATE_EXPRESSION ))
do
    COMMANDS
done

例えば、iの値が0から9に変わる10回のループを実行したい場合、forループは次のようになります:

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

詳細を解説します:

  • i=0 is the assignment expression here. It’s run only once before the loop is executed, which is why it’s useful for initializing a variable.
  • i<10 is our condition expression. This expression is evaluated before each iteration of a loop. If it is equal to zero (which means the same as “true” in Bash), the next iteration is not run.
  • i++ is our update expression. It’s run after each iteration of a loop.
The structure of our for loop

リスト内の要素をサイクル

3つの式構文に加えて、in キーワードを使用してforループを定義することもできます。この代替構文は、一連のアイテムを反復処理するために使用されます。

最も基本的な例は、inキーワードの後に反復処理したいアイテムのセットをスペースで区切って一覧表示することです。例えば:

for i in 0 1 2 3 4 5 6 7 8 9 # space-separated list items
do
    echo $i
done

コマンドによって出力されるアイテムを反復処理することもできます。

for i in $(seq 0 1 9)

$()表記は、一般的にコマンド置換に使用されます — コマンドを実行し、その出力を囲む親コマンドの入力として使用します。

整数を反復処理する場合は、Bashの組み込みの範囲構文を使用する方が良いです。これは、seqコマンドよりも効率的です。ただし、この構文はより新しいBashバージョンでのみ利用可能です。

  • for i in {0..9}、Bash 3で利用可能。
  • for i in {0..9..1}、Bash 4で利用可能。ここで、最後の数値が増分を表します。

同様に、文字列を反復処理することもできます。

for s in 'item1' 'item2' 'item3'

パターンに一致するファイルを取得するためにグロブを使用

前のセクションで議論された for ループの一般的な使用例の1つは、個々のファイルを反復処理することです。

これに取り組むために、まず「グロブ展開」と呼ばれるものを扱う必要があります。これは、パターンマッチングを使用してファイル名を指定できるBashの機能です。これらのパターンを定義するために使用する特殊文字をワイルドカードと呼びます。

この点について詳しく説明する前に、いくつか具体的な例を見てみましょう:

  • echo *:現在のディレクトリ内のすべてのファイルの名前を返すコマンドで、隠しファイルは除外されます。
  • echo *.txt:現在のディレクトリ内で、txt拡張子を持つ非隠しファイルの名前を返すコマンドです。
  • echo ????:現在のディレクトリ内で、4文字のファイル名をすべて返すコマンドです。

ここで使用した ワイルドカード は * と ? です。もう1つのワイルドカードもありますが、使用しませんでした。以下に概要を示します:

  • アスタリスク (*) は、ファイルやディレクトリ名での任意の数の文字(0を含む)を表します。
  • 疑問符 (?) は、ファイルやディレクトリ名での1文字を表します。
  • 二重アスタリスク (**) は、フルファイルパス内の任意の数の文字を表します。これはBash 4以降の機能であり、shopt -s globstarを実行して有効にする必要があります。
  • 角括弧 ([]) は、ファイルやディレクトリ名の一連の記号内の文字を表すために使用されます。たとえば [st]ake は、sake または take という名前のファイルを見つけますが、stake は見つかりません。

グロブ展開を使用する際には、全ての隠しファイル(ファイル名がピリオド.で始まるファイル)が無視されることに注意してください。

角括弧表記 には、以下のような少し複雑な機能があります:

  • 最初と最後の値によって定義される範囲- 例:[1-8]
  • 特定の文字を削除するために、括弧の中で最初の文字として!を使用- 例:[!3]

これらの特殊文字のうち1つを、意味を持たない通常の文字として扱うには、単にその前にバックスラッシュを入れます- 例:\?

A few examples of globbing

ファイルをforループを使用して反復処理する

グロブ展開の基本をカバーしたので、それを使用してファイルを反復処理する方法を見てみましょう。

単純に、forループ自体でグロブ演算子を使用できます。現在のディレクトリ内の各ファイルの名前を出力するループの単純な例を以下に示します:

for f in *
do
    echo $f
done

現在のディレクトリ内およびそのサブディレクトリ内の各ファイルの名前を出力するには、bash --versionを実行してBash 4.0以上を実行していることを確認し、次のコマンドを実行できます:

shopt -s globstar # enables using **
for f in **
do
    echo $f
done

ヒント: より古いバージョンのBashを実行している場合、このためにforループとグロブ展開を使用することはできません。最善の対処法は、findコマンドですが、この記事ではそれについては説明しません。

これらはもちろん、実行できる最も単純なループのいくつかにすぎませんが、できることはもっとたくさんあります。たとえば、フォルダ内のすべてのJPGファイルの名前を一貫した連番のファイル名に変更するには、次のように実行できます:

i=1
for f in *.jpg
do
    mv -i -- "$f" "image_$i.jpg"
    let i=i+1
done
Checking the Bash version, then running our script

条件が真の間コードを実行する

forループ以外にもBashで使用できるループのタイプには、whileがあります: このタイプのループは特定の条件が真の間実行されます。

構文はforループの構文に似ています:

while CONDITION
do
    COMMANDS
done

実践例として、ファイルを行ごとに読み取り(先頭や末尾の空白を除く)してファイルの末尾に達するまでの方法は以下の通りです:

while read -r line
do
    echo "$line"
done < FILENAME # Replace FILENAME with the path to a text file you'd like to read
Using a while loop inside our script to have it print itself

forループをwhileループで置き換えることもできます。たとえば、0から9まで反復処理する場合は:

i=0
while [ $i -lt 10 ]
do
    echo $i
    let i=i+1
done

無限ループも理論的に実行できます。次にコマンドの例を示します:

while true
do
    echo "running forever"
done

ヒント:スクリプトを終了するには、Ctrl+Cを押してください。

この無限ループは最初は無意味に見えるかもしれませんが、break文と組み合わせると実際にはかなり有用です。

ループから抜け出す

break文はループから抜け出すために使用されます。

これにより、無限ループを実行し、いずれかの中断条件が発生した場合にそれから抜け出すことができます。

単純な例を見てみると、0から9まで実行されるループを次のような無限ループで再現できます:

i=0while true
do
    if [ $i -eq 10 ]
    then
        break
    fi
    echo $i
    let i=i+1
done

複数の入れ子のあるwhileループがある場合、breakステートメントの後に数字を追加すると、どのレベルのループから脱出するかを指定できます:break 1breakと同じで、最も近い囲んでいるループから脱出します。break 2は1つ上のループから脱出します、など。

ここでは、forループを使用して、単語が“bash”に出会うまで、4文字の単語の組み合わせを反復処理する簡単な例を見てみましょう。

for l4 in {a..z}
do
    for l3 in {a..z}
    do
        for l2 in {a..z}
        do
            for l1 in {a..z}
            do
                echo "$l4$l3$l2$l1"
                if [ $l4 = "b" -a $l3 = "a" -a $l2 = "s" -a $l1 = "h" ]
                then
                    break 4
                fi
            done
        done
    done
done

A related keyword that’s also worth a mention is continue, which skips to the next iteration of the loop. Just like break, it also takes an optional numeric argument that corresponds to the loop level.

ここでは、Eを含む単語をすべてスキップする愚かな例があります:

for l4 in {a..z}
do
    if [ $l4 = "e" ]
    then
        continue
    fi
    for l3 in {a..z}
    do
        if [ $l3 = "e" ]
        then
            continue
        fi
        for l2 in {a..z}
        do
            if [ $l2 = "e" ]
            then
                continue
            fi
            for l1 in {a..z}
            do
                if [ $l1 = "e" ]
                then
                    continue
                fi
                echo "$l4$l3$l2$l1"
                if [ $l4 = "b" -a $l3 = "a" -a $l2 = "s" -a $l1 = "h" ]
                then
                    break 4
                fi
            done
        done
    done
done

すべてのこれらのcontinueステートメントを最も深いループレベルで実行することもできます:

for l4 in {a..z}
do
    for l3 in {a..z}
    do
        for l2 in {a..z}
        do
            for l1 in {a..z}
            do
                if [ $l4 = "e" ]
                then
                    continue 4
                fi
                if [ $l3 = "e" ]
                then
                    continue 3
                fi
                if [ $l2 = "e" ]
                then
                    continue 2
                fi
                if [ $l1 = "e" ]
                then
                    continue
                fi
                echo "$l4$l3$l2$l1"
                if [ $l4 = "b" -a $l3 = "a" -a $l2 = "s" -a $l1 = "h" ]
                then
                    break 4
                fi
            done
        done
    done
done
Our script stops once it generates the word “bash”

シェルスクリプトでユーザー入力を取得する方法

時々、ユーザーが初期スクリプト引数を使用するのではなく、スクリプトと直接やり取りすることを望むことがあります。その場合、readコマンドが役立ちます。

ユーザー入力を受け取り、NAMEという変数に保存するには、次のコマンドを使用します:

read NAME 

これは、コマンド名と入力を保存する変数だけで構成されるコマンドの最も簡単な形です。

より頻繁には、ユーザーにプロンプトを表示して入力内容を知らせたいことがあるでしょう。その際には、-p引数を使用し、その後に好みのプロンプトを書きます。

ここに、変数 NAME に名前を尋ねる方法が示されています:

read -p "Your name: " NAME
echo "Your name is $NAME." # this line is here just to show that the name has been saved to the NAME variable
The script saves our input to a variable and then prints it

文字列内の特殊文字の表示

Bashには、慎重に使用する必要があるいくつかの特殊文字があります。たとえば、ファイル名内のスペース、文字列内の引用符、あるいはバックスラッシュなどです。

Bashに特殊な意味を無視するよう指示するには、それらを「エスケープ」するかリテラル引用符で囲むことができます。

エスケープ」とは、特殊文字をBashにその特殊な意味なしでただの文字として扱うということです。そのためには、その文字の前にバックスラッシュを記述します。

たとえば、ファイル名がimg \ 01 *DRAFT*という場合を考えます。Bashでは、このように参照できます:

img\ \\\ 01\ \*DRAFT\*

以下は、Bashにおける特殊文字の非網羅的なリストです:

  • 空白: スペース、タブ、空行
  • 引用符: ”、“”
  • 括弧や中括弧、角括弧: ( )、{ }、[ ]
  • パイプとリダイレクト: |、 <、 >
  • ワイルドカード: *、?
  • その他: !、#、;、=、&、~、`
  • エスケープ文字そのもの: \

ただし、Bashに新しい場合は、どの文字に特殊な意味があるかを覚えるのは面倒かもしれません。そのため、多くの状況では、リテラル引用符を使用する方が簡単かもしれません: 特殊文字を含むテキストをシングルクォートで囲み、そのクォート内のすべての特殊文字が無視されます。

Here’s how that would look for our example: 

'img \ 01 *DRAFT*'

特殊文字を使用したい場合はどうすればよいですか?他の文字をエスケープしたい場合は、バックスラッシュを使用して文字ごとにエスケープすることができますが、特殊文字以外のすべてをリテラルクオートで囲むことで手間を省くこともできます。

例えば、複数のファイルがimg \ 01 *v1 DRAFT*img \ 01 *v2 DRAFT*img \ 01 *ROUGH DRAFT*などという名前である場合、これらのファイル名に一致させるためにグロブ展開を使用したい場合、次のように書くことができます:

'img \ 01 *'*' DRAFT*'
This glob expansion finds all of our 3 oddly-named files

書きたい内容にシングルクォートが含まれている場合 — たとえばimg \ 01 *’FINAL’* — 類似の戦略を使用してリテラル文字列とエスケープを組み合わせることができます:

'img \ 01 '\''FINAL'\'

Bashで文字列を連結する方法

例えば、名前と苗字などの2つ以上の文字列変数を持っているとします:

FIRST_NAME="Johnny"LAST_NAME="Appleseed"

これらの変数を1つの文字列に結合するには、おそらくカスタムデリミターを使用して、これら2つの変数からなる新しい文字列を作成します:

NAME="$LAST_NAME"', '"$FIRST_NAME"

また、これには、インライン変数を使用して二重引用符を使用することもできます。変数名を周囲のテキストから区別するために波括弧を使用します:

NAME="${LAST_NAME}, ${FIRST_NAME}"

Bashでは、+=演算子を使用してテキストを文字列に追加することもできます:

NAME='Appleseed'NAME+=', 'NAME+='Johnny'
Examples of different ways of stringing together text

文字列内でコマンドを実行する

Bashは、コマンド置換としても知られる、コマンドの出力を文字列内で使用することも可能です。単純にコマンドを$()で囲みます。たとえば、現在のタイムスタンプを表示するには、次のように実行できます:

echo "Current timestamp: $(date)"
Using command substitution to print the current timestamp

この構文は、以前のforループの例からもおなじみかもしれません。そのときには、0から9までの整数のシーケンスを反復処理しました:

for i in $(seq 0 1 9)
do
    echo $i
done

置換されたコマンドはサブシェルで実行されます。つまり、たとえば、コマンド中に作成された変数は、スクリプトを実行している環境に影響を与えないということです。

シェルスクリプトでの終了コードの設定と返却

より複雑なスクリプトの場合、スクリプトが正常に実行されたかエラーが発生したかを人々に伝えるために、通常は0から255の間の数値である終了コードを返すことが一般的です。

使用する数値については、公式のBashマニュアルでこれらが指定されています:

  • 0: プログラムは正常に実行されました。
  • 2: プログラムが誤って使用されました(たとえば、無効または不足している引数のため)。
  • 1および3-124: ユーザー定義のエラー。
  • 126: コマンドが実行不可です。
  • 127: コマンドが見つかりませんでした。
  • 125および128-255: シェルが使用するエラーステータス。プロセスがシグナルNによって終了された場合、終了ステータスは128 + Nとなります。

数字がゼロ以外のすべての数値はエラーを示しています。終了コード1 は一般的に一般的なエラーのために使用されます。ほとんどの場合、2 より上の終了コードを使用する必要はありません。

スクリプトから終了コードを返すには、exit コマンドを使用します。例えば、コードが 2 で終了する場合は、exit 2 と書きます。

スクリプトでexit コマンドを使用しないか、コードを指定せずにコマンドを使用すると、スクリプト内で最後に実行されたコマンドの終了ステータスが返されます。

シェルで直近に実行されたコマンドの終了コードを取得するには、$? 変数を使用します:echo $?

関数の呼び出し方

長いスクリプトや同じコードの塊が繰り返されるスクリプトを書く場合、いくつかのコードを関数に分離したいかもしれません。関数を定義するには、2 つの形式があります。いずれの場合も、関数コード全体は中括弧内に含まれ、関数の宣言だけが異なります。

よりコンパクトな形式では、関数名に続いて括弧を使用して関数を宣言します:

function_name () {
    echo "This is where your function code goes"
}

もう一つの形式では、関数名の前にfunction キーワードを使用します。

function function_name {
    echo "This is where your function code goes"
}

関数はスクリプト内で呼び出される前に宣言する必要があります。関数を呼び出す際は、関数名をコマンドとして実行するのと同様にします。

function_name

変数を使用して関数にデータを渡す

Bashでは、関数は引数を取ることができません。関数に情報を送るためには、スクリプト内でグローバル変数を使用する必要があります。

例:

is_your_name_defined () {
    if [ -z "$YOUR_NAME" ]
    then
        echo "It doesn't seem like I have your name."
    else
        echo "Is this your name: ${YOUR_NAME}?"
    fi
}
read -p "Your name: " YOUR_NAME

is_your_name_defined

他の言語で使われる方法とは異なり、関数内で定義した変数はグローバルであり、スクリプト外のコードでも見えます。関数内でスクリプト外のすべてのコードからアクセスできないように変数をローカルにスコープするには、localキーワードを使用してください。例:local i=0

関数から値を返したい場合は、グローバル変数を使用する必要があります。Bashでは、returnキーワードを使用してのみ終了コードを返すことができます。例を見てみましょう。

is_your_name_defined () {
    if [ -z "$YOUR_NAME" ]
    then
        MESSAGE="It doesn't seem like I have your name."
    else
        MESSAGE="Is this your name: ${YOUR_NAME}?"
    fi
}
read -p "Your name: " YOUR_NAME

is_your_name_defined

echo $MESSAGE
The output of our script depends on the values entered

まとめ

Bashスクリプティングを使用すると、UNIXベースのオペレーティングシステム上でさまざまな作業を行うことができます。この記事では、Bashスクリプティングの基本、スクリプトの作成と実行、文字列の操作、コード内でのループ処理などを取り上げました。これが、自分のニーズに合ったパワフルなBashスクリプトを作成するための良いスタートになることを願っています。

Bashには、ファイルシステムナビゲーションを含む、最も便利なコマンドやその他の機能について学ぶことができることがたくさんあります。次に取り上げてほしいトピックについてコメントでお知らせください。

関連記事:

Source:
https://petri.com/shell-scripting-bash/