Linux Professional Institute Learning Logo.
main contentにスキップ
  • ホーム
    • 全てのリソース
    • LPI学習教材
    • コントリビューターになる
    • Publishing Partners
    • Publishing Partnerになる
    • About
    • FAQ
    • コントリビューター
    • Roadmap
    • 連絡先
  • LPI.org
3.3 レッスン 1
課題 1: Linuxコミュニティとオープンソースのキャリア
1.1 ポピュラーなOSとLinuxの発展
  • 1.1 レッスン 1
1.2 主なオープンソースのアプリケーション
  • 1.2 レッスン 1
1.3 オープンソースソフトウエアとライセンス
  • 1.3 レッスン 1
1.4 ICTスキルとLinuxでの作業
  • 1.4 レッスン 1
課題 2: Linuxシステムで自分の手法を見つける
2.1 コマンドラインの基本
  • 2.1 レッスン 1
  • 2.1 レッスン 2
2.2 コマンドラインのヘルプ機能の利用
  • 2.2 レッスン 1
2.3 ディレクトリの利用とファイルの一覧
  • 2.3 レッスン 1
  • 2.3 レッスン 2
2.4 ファイルの作成、移動と削除
  • 2.4 レッスン 1
課題 3: コマンドラインの力
3.1 コマンドラインでのファイル圧縮
  • 3.1 レッスン 1
3.2 ファイルの検索と展開
  • 3.2 レッスン 1
  • 3.2 レッスン 2
3.3 コマンドをスクリプトにする
  • 3.3 レッスン 1
  • 3.3 レッスン 2
課題 4: Linuxオペレーティングシステム
4.1 オペレーティングシステムの選択
  • 4.1 レッスン 1
4.2 コンピュータハードウエアの理解
  • 4.2 レッスン 1
4.3 データの保管場所
  • 4.3 レッスン 1
  • 4.3 レッスン 2
4.4 ネットワーク上のコンピュータ
  • 4.4 レッスン 1
課題 5: セキュリティとファイルパーミッション
5.1 セキュリティの基本と、ユーザタイプの確認
  • 5.1 レッスン 1
5.2 ユーザとグループの作成
  • 5.2 レッスン 1
5.3 ファイルのパーミッションと所有権の管理
  • 5.3 レッスン 1
5.4 特別なディレクトリとファイル
  • 5.4 レッスン 1
How to get certified
  1. 課題 3: コマンドラインの力
  2. 3.3 コマンドをスクリプトにする
  3. 3.3 レッスン 1

3.3 レッスン 1

Certificate:

Linux Essentials

Version:

1.6

Topic:

3 コマンドラインの力

Objective:

3.3 コマンドをスクリプトにする

Lesson:

1 of 2

はじめに

ここまではシェルからコマンドを実行することを学んできましたが、ファイルにコマンドを書いて実行可能なファイルとすることもできます。 ファイルが実行されると、それらのコマンドが次々と実行されます。このような実行可能ファイルを スクリプト と呼び、Linuxシステム管理者にとって極めて重要なツールです。Bashはシェルであるだけでなく、一種のプログラミング言語であると考えることができます。

文字を表示する

ここまでのレッスンで見たことがあるコマンドから見ていきましょう: echo は引数を標準出力に表示します。

$ echo "Hello World!"
Hello World!

次に、このコマンドを new_script という新しいファイルにリダイレクトします。

$ echo 'echo "Hello World!"' > new_script
$ cat new_script
echo "Hello World!"

ファイル new_script は、前の例と同じコマンドを内容としています。

スクリプトを実行可能にする

このスクリプトを、望むように実行可能とするために必要な手順を示しましょう。他のコマンドの名前を入力するのと同様に、スクリプトの名前をタイプすればよいと考えるかもしれません:

$ new_script
/bin/bash: new_script: command not found

現在のディレクトリに new_script が存在するはずです。エラーメッセージは、 ファイル が存在しないではなく、 コマンド が存在しないとなっていることがポイントです。ここで、Linuxがコマンドと実行可能ファイルを扱う方法を述べておきましょう。

コマンドと PATH

例えば、シェルに ls コマンドを入力すると、ファイルシステムに存在する ls というファイルを実行します。which を使って調べてみましょう:

$ which ls
/bin/ls

ディレクトリの内容を見たいときに毎回 ls の絶対パスを入力するのはすぐに面倒になります。そのため、Bashは 環境変数 の中に、実行するコマンドがあると思われるすべてのディレクトリを納めています。この変数の内容は、echo を使って見ることができます。

$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

シェルは、それぞれがコロン(:)で区切られたディレクトリで、コマンドを見つけようとします。この中に /bin はありますが、現在のディレクトリは存在しないことがポイントです。シェルはこれらのディレクトリそれぞれから new_script を探しますがどこにも無いので、例に示したようなエラーとなるのです。

これを解決するには、3つの方法があります: new_script を PATH ディレクトリの1つに移動するか、現在のディレクトリを PATH に追加するか、あるいは、スクリプトの呼び出し方法を変更します。最後の方法が最も簡単で、ドットスラッシュ(./)を使用して、スクリプトを呼び出すときに 現在のディレクトリ を指定するのです。

$ ./new_script
/bin/bash: ./new_script: Permission denied

エラーメッセージが変わり、ある程度の進展があったことが分かります。

実行パーミッション

この場合には、まず ls -l を使ってファイルを調べます:

$ ls -l new_script
-rw-rw-r-- 1 user user 20 Apr 30 12:12 new_script

このファイルのパーミッションが、デフォルトの 664 に設定されていることがわかります。このファイルには、まだ 実行パーミッション がセットされていません。

$ chmod +x new_script
$ ls -l new_script
-rwxrwxr-x 1 user user 20 Apr 30 12:12 new_script

このコマンドは、すべての ユーザーに実行許可を与えます。このパーミッションにはセキュリティ上のリスクがありますが、今のところは許容可能なレベルです。

$ ./new_script
Hello World!

やった! スクリプトを実行できました。

インタプリタの指定

テキストをファイルに入力し実行可能と設定すれば、実行できることを見てきました。new_script は通常のテキストファイルですが、Bashで解釈させることができました。しかし、スクリプトがPerlまたはPythonで記述されている場合はどうでしょうか?

スクリプトの最初の行に、使用するインタープリタの種類を指定することは非常に良い習慣です。この行は一般的に シェバング(shebang)行(訳注: シバンあるいはシェバンという発音が一般的です)、あるいは単に バング行(bang line)と呼ばれ、そのファイルを実行する方法をシステムに示します。今はBashを学習しているので、再度 which を使用して、Bashの実行可能ファイルへの絶対パスを指定します:

$ which bash
/bin/bash

シェバンはハッシュ記号( # )と感嘆符( ! )で始まり、その後に上記の絶対パスを書きます。テキストエディターで new_script を開き、シェバンを挿入しましょう。またこの機会に、スクリプトに コメント を挿入してみましょう。コメントはインタープリタでは無視されますが、スクリプトを理解したい他のユーザーのために書くものです。

#!/bin/bash

# This is our first comment. It is also good practice to document all scripts.
# 訳注: コメントを日本語で書くこともできますが、システムの言語設定によって
#     表示・編集できないことがあるので、英語で記入することが好まれます

echo "Hello World!"

ファイル名にも変更を加えましょう: このファイルを new_script.sh として保存します。ファイルのサフィックス ".sh" は、ファイルの実行に一切関係ありません。Pythonスクリプトを .py サフィックスで識別するのと同様に、bashスクリプトには .sh または .bash を付けるのが慣例です。

代表的なテキストエディタ

Linuxユーザーは、グラフィカルなテキストエディターが利用できない環境で作業する必要があることがよくあります。そのため、コマンドラインでのテキストファイル編集について、少なくともある程度慣れておくことを強く推奨します。最も一般的なテキストエディターは、vi と nano の2つです。

vi

vi は由緒あるテキストエディタで、現存するほとんどすべてのLinuxシステムにデフォルトでインストールされています。vi は、そのインターフェイスを維持しつついくつかの機能を追加した、vim すなわち vi IMproved と呼ばれるクローンを生み出しました。 初学者にとって、vi を使って作業するのは気が遠くなるほどですが、このエディタは人気があり、その多くの機能を学ぶユーザに愛されています。

vi とメモ帳などのアプリケーションの最も重要な相違点は、vi には3つのモードがあることです。起動時にはキー h 、 j 、 k 、 l はナビゲーション(移動)に使われて、入力されることはありません。この ナビゲーションモード で、 i を押すと 挿入モード になります。このモードでは、通常通りに文字の入力が行えます。挿入モード を抜けるには、 ESC を押すと ナビゲーションモード に戻ります。ナビゲーションモード で、 : を押すと コマンドモード に入り、保存や削除、終了、オプションの変更といった操作を行えます。

vi には学習曲線があり、さまざまなモードを使うことで、経験豊富なユーザーほど他のエディタよりも効率的に作業が行えます。

nano

nano は新しいツールで、vi よりもシンプルで使いやすく作られています。nano にはモードがありません。起動するとすぐに入力を開始することができ、Ctrl を使って画面下部に表示されているツールにアクセスすることができます。

                         [ Welcome to nano.  For basic help, type Ctrl+G. ]
^G ヘルプ    ^O 書き込み  ^W 検索      ^K 切り取り  ^J 均等割付  ^C カーソル位置
^X 終了        ^R 読み込み  ^\ 置換      ^U 貼り付け  ^T スペル確認^_ 行を指定

テキストエディタは個人の好みの問題であり、このレッスンではどれを使っても構いません。しかし、1つ以上のテキストエディタに慣れ親しんで快適に使いこなせるようになっておくと、報われることが多いでしょう。

変数

変数はプログラミング言語の重要なパーツであり、Bashも例外ではありません。ターミナルから新しいセッションを開始すると、シェルはすでにいくつかの変数を設定しています。PATH 変数はこの例の1つです。これらがシェル環境の特性を定義するので、環境変数(environment variables)と呼びます。環境変数は変更や追加できますが、ここではスクリプトにおける変数設定に焦点を当てましょう。 スクリプトを次のように変更します:

#!/bin/bash

# This is our first comment. It is also good practice to comment all scripts.

username=Carol

echo "Hello $username!"

この例では、username という 変数 を作成し、Carol という 値 を代入しています。変数名、等号、代入する値の間に、空白を置かないことに注意しましょう。

次の行では、echo コマンドで変数を使用していますが、変数名の前にドル記号($)を置きます。 このドル記号は重要で、username を普通の単語ではなく変数名として扱うことをシェルに指示しています。コマンドに $username を与えると 置換 が行われて、変数名 が変数に割り当てた 値 に置き換えられます。

新しいスクリプトを実行して、出力を見てみましょう:

$ ./new_script.sh
Hello Carol!
  • 変数名には、英数字とアンダースコア(_)のみが使用でき、大文字と小文字は区別されます。Username と username は、別の変数として扱われます。(訳注: 変数名に日本語は使えません)。

  • 変数の置換は、{ } で囲んで ${username} と書くこともできます。

  • Bashの変数に型はなく、すべてが文字列として扱われます。そのため、Bashでの数値演算は、C/C++などの他のプログラミング言語に比べると面倒です。

#!/bin/bash

# This is our first comment. It is also good practice to comment all scripts.

username=Carol
x=2
y=4
z=$x+$y
echo "Hello $username!"
echo "$x + $y"
echo "$z"
$ ./new_script.sh
Hello Carol!
2 + 4
2+4

変数でクオートを使う

変数 username の値を次のように変更してみましょう:

#!/bin/bash

# This is our first comment. It is also good practice to comment all scripts.

username=Carol Smith

echo "Hello $username!"

このスクリプトを実行すると、次のようなエラーになります:

$ ./new_script.sh
./new_script.sh: line 5: Smith: command not found
Hello !

Bashはインタープリタであるため、スクリプトを1行ずつ 解釈 することを覚えておきましょう。username=Carol は、変数 username に値 Carol を割り当てるものと正しく解釈されます。しかし、その次のスペースをその割り当ての終わりを示すものと解釈し、Smith を次のコマンドの名前として解釈します。スペースと名前 Smith を変数の新しい値に含めるためには、名前を二重引用符( " )で囲みます。

#!/bin/bash

# This is our first comment. It is also good practice to comment all scripts.

username="Carol Smith"

echo "Hello $username!"
$ ./new_script.sh
Hello Carol Smith!

Bashでは、シングルクオート( ' )とダブルクオート( " )の扱いが異なるので注意が必要です。ダブルクオートは引用内での置換が解釈されるため “弱い” 引用符です。対して、シングルクオートは置換が行われないので、 “強い” 引用符です。例を見てみましょう:

#!/bin/bash

# This is our first comment. It is also good practice to comment all scripts.

username="Carol Smith"

echo "Hello $username!"
echo 'Hello $username!'
$ ./new_script.sh
Hello Carol Smith!
Hello $username!

2番目の echo コマンドでは、$username から Carol Smith への置換が解釈されず、入力した通りの文字列が表示されます。

引数

Linuxユーティリティで引数を使う方法は既に学習しました。例えば、rm testfile では、rm が実行可能なコマンドで、testfile が引数です。スクリプトの実行時に引数を渡して、その振る舞いを変更する事ができます。簡単に実装することができます。

#!/bin/bash

# This is our first comment. It is also good practice to comment all scripts.

username=$1

echo "Hello $username!"

スクリプト内部で username に値を直接割り当てるのではなく、新しい変数 $1 の値を割り当てます。これは、最初の引数 の値を意味しています。

$ ./new_script.sh Carol
Hello Carol!

最初から9個目までの引数は、この方法で扱えます。9個を超える引数も扱えるのですが、このレッスンの範囲を超えてしまいます。2つの引数を扱う例を見てみましょう:

#!/bin/bash

# This is our first comment. It is also good practice to comment all scripts.

username1=$1
username2=$2
echo "Hello $username1 and $username2!"
$ ./new_script.sh Carol Dave
Hello Carol and Dave!

引数を使うときに大切なことがあります: 上の例では、2つの引数 Carol と Dave が、それぞれ $1 と $2 に割り当てられています。例えば、2番目の引数が無かったとしても、シェルはエラーとなりません。$2 に、単に null が割り当てられるだけです。

$ ./new_script.sh Carol
Hello Carol and !

この場合、スクリプトに、条件 に応じて表示する 出力 を変更するロジックを導入するのが良いでしょう。まず別の便利な変数を導入して、if 文 を作成します。

引数の数を調べる

$1 や $2 は引数の位置に応じた値を保持します。別の変数 $# は、引数の数 を保持します。

#!/bin/bash

# This is our first comment. It is also good practice to comment all scripts.

username=$1

echo "Hello $username!"
echo "Number of arguments: $#."
$ ./new_script.sh Carol Dave
Hello Carol!
Number of arguments: 2.

条件分岐

プログラミングにおける条件判断の利用は広大なトピックですから、このレッスンで深くは取り上げません。Bash における条件判断の 書式 に焦点を当て、他のプログラミング言語と異なる点を説明します。

まず、達成したいゴールを説明します。1人のユーザーへの挨拶を出力する単純なスクリプトを作ります。ユーザーが1人ではない場合には、エラーメッセージを出力するようにしましょう。

  • 調べたい 条件 は、(コマンドに指定された)ユーザー数です。それは、$# 変数に格納されています。$# が 1 であることを確認します。

  • もし、条件が 真 であれば、取るべきアクションはそのユーザーに挨拶することです。

  • また、条件が 偽 であれば、エラーメッセージを表示します。

ロジックが整理できたので、そのロジックを実装するための 書式(書き方)に進みましょう。

#!/bin/bash

# A simple script to greet a single user.

if [ $# -eq 1 ]
then
  username=$1

  echo "Hello $username!"
else
  echo "Please enter only one argument."
fi
echo "Number of arguments: $#."

条件判断のロジックは、if と fi の間に置きます。調べる条件はカギ括弧 [ ] の間に置き、条件が真であるときに実行するアクションは then の後に置きます。かぎ括弧内やロジック(論理式)に含まれるスペースに注意しましょう。それらのスペースを省略するとエラーになります。

このスクリプトは、あいさつかエラーメッセージを表示し、最後に 引数の数 を表示します。

$ ./new_script.sh
Please enter only one argument.
Number of arguments: 0.
$ ./new_script.sh Carol
Hello Carol!
Number of arguments: 1.

if 文についてまとめておきましょう。-eq は、数値の比較 に使います。例の場合は、$# の値が1と 等しい ことを調べています。比較には次のものも使えます:

-ne

等しくない

-gt

より大きい

-ge

より大きいか等しい

-lt

より小さい

-le

より小さいか等しい

演習問題

  1. シェルに以下を入力しました:

    $ PATH=~/scripts
    $ ls
    ls: command not found

    ls コマンドは、/bin/ls にあります。 /bin がPATH環境変数に含まれていないので、コマンドを見つけることができません。

    • ユーザーは何をしたのでしょうか?

    • PATH の現在の値に、新しいディレクトリ ~/scripts を追加するコマンドは何でしょう?

  2. 次のスクリプトについて考えます。ここでは、2番目の条件を調べるために、elif を使っています。

    >  /!bin/bash
    
    > fruit1 = Apples
    > fruit2 = Oranges
    
      if [ $1 -lt $# ]
      then
        echo "This is like comparing $fruit1 and $fruit2!"(参考訳: $fruit1と$fruit2を比べるよ!)
    > elif [$1 -gt $2 ]
      then
    >   echo '$fruit1 win!'
      else
    >   echo "Fruit2 win!"
    > done
    • マーク > が付いた行にはエラーがあります。エラーを修正しましょう。

  3. 前問のスクリプトを guided1.sh とします。以下を実行すると何が出力されますか?

    $ ./guided1.sh 3 0
    $ ./guided1.sh 2 4
    $ ./guided1.sh 0 1

発展演習

  1. 2つの引数が渡されていることをチェックして、それらの引数を逆順に表示するスクリプトを書いて下さい。 この例を参考にして下さい(これとは違うコードでも構いませんが、出力は同じになるように):

    if [ $1 == $number ]
    then
      echo "True!"
    fi
  2. 数値ではないものを比較する演算子は何でしょう? インターネットで、この演算子と -eq を使う場合の違いを調べて下さい。

  3. 現在のディレクトリを保持している環境変数があります。env を使って、その変数の名前を見つけましょう。

  4. 問題2と3で学んだことを使って、1つの引数を受け付ける短いスクリプトを書いて下さい。引数が渡されたら、それが現在のディレクトリ名に一致するかを調べます。一致したら yes を表示し、しなければ no を表示します。

まとめ

このレッスンでは、次のことを学びました:

  • 簡単なスクリプトの作り方と実行方法

  • シェバンを使ってインタープリタを指定する方法

  • スクリプトの中で変数をセットして使う方法

  • スクリプト内で引数を扱う方法

  • if 文の組み立て方

  • 数値演算子を使って数値を比較する方法

演習で使用したコマンド:

echo

文字列を標準出力に表示する。

env

すべての環境変数を標準出力に表示する。

which

コマンドの絶対パスを表示する。

chmod

ファイルのパーミッションを変更する。

演習で使用した特殊変数

$1, $2 …​ $9

スクリプトに渡された位置引数を保持する。

$#

スクリプトに渡された引数の数を保持する。

$PATH

システムが使用する実行可能ファイルを収めた一連のディレクトリを保持する。

演習で使用した演算子:

-ne

等しくない

-gt

より大きい

-ge

より大きいか等しい

-lt

より小さい

-le

より小さいか等しい

演習の解答

  1. シェルに以下を入力しました:

    $ PATH=~/scripts
    $ ls
    ls: command not found

    ls コマンドは、/bin/ls にあります。 /bin がPATH環境変数に含まれていないので、コマンドを見つけることができません。

    • ユーザーは何をしたのでしょうか?

      PATHの内容を、ディレクトリ ~/scripts で上書きしました。PATHに(/bin/lsディレクトリが)含まれていないため、ls コマンドはもう見つかりません。この変更は現在のセッションにのみ影響し、ログアウトすると変更が元に戻ることに注意しましょう。

    • PATH の現在の値に、新しいディレクトリ ~/scripts を追加するコマンドは何でしょう?

      PATH=$PATH:~/scripts

  2. 次のスクリプトについて考えます。ここでは、2番目の条件を調べるために、elif を使っています。

    >  /!bin/bash
    
    > fruit1 = Apples
    > fruit2 = Oranges
    
      if [ $1 -lt $# ]
      then
        echo "This is like comparing $fruit1 and $fruit2!"
    > elif [$1 -gt $2 ]
      then
    >   echo '$fruit1 win!'
      else
    >   echo "Fruit2 win!"
    > done
    • マーク `>`が付いた行にはエラーがあります。エラーを修正しましょう。

      #!/bin/bash
      
      fruit1=Apples
      fruit2=Oranges
      
      if [ $1 -lt $# ]
      then
        echo "This is like comparing $fruit1 and $fruit2!"
      elif [ $1 -gt $2 ]
      then
        echo "$fruit1 win!"
      else
        echo "$fruit2 win!"
      fi
  3. 以下を実行すると何が出力されますか?

    $ ./guided1.sh 3 0

    Apples win!

    $ ./guided1.sh 2 4

    Oranges win!

    $ ./guided1.sh 0 1

    This is like comparing Apples and Oranges!

発展演習の解答

  1. 2つの引数が渡されていることをチェックして、それらの引数を逆順に表示するスクリプトを書いて下さい。 この例を参考にして下さい(これとは違うコードでも構いませんが、出力は同じになるように):

    if [ $1 == $number ]
    then
      echo "True!"
    fi
    #!/bin/bash
    
    if [ $# -ne 2 ]
    then
      echo "Error"
    else
      echo "$2 $1"
    fi
  2. 数値ではないものを比較する演算子は何でしょう? インターネットで、この演算子と -eq を使う場合の違いを調べて下さい。

    == を使うと、文字列 の比較を行います。つまり、両方の変数の文字が正確に一致している場合に、条件が真になります。

    abc == abc

    真

    abc == ABC

    偽

    1 == 1

    真

    1+1 == 2

    偽

    文字列比較で数値のテストを行った場合は、予期しない振る舞いとなることがあります。

  3. 現在のディレクトリを保持している環境変数があります。env を使って、その変数の名前を見つけましょう。

    PWD

  4. 問題2と3で学んだことを使って、1つの引数を受け付ける短いスクリプトを書いて下さい。引数が渡されたら、それが現在のディレクトリ名に一致するかを調べます。一致したら yes を表示し、しなければ no を表示します。

    #!/bin/bash
    
    if [ "$1" == "$PWD" ]
    then
      echo "yes"
    else
      echo "no"
    fi

Linux Professional Insitute Inc. All rights reserved. 学習資料をご覧ください: https://learning.lpi.org
ここでの作成物は、Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Licenseの下でライセンスされています。

次のレッスン

3.3 コマンドをスクリプトにする (3.3 レッスン 2)

次のレッスンを読む

Linux Professional Insitute Inc. All rights reserved. 学習資料をご覧ください: https://learning.lpi.org
ここでの作成物は、Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Licenseの下でライセンスされています。

LPIは非営利団体です。

© 2023 Linux Professional Institute(LPI)は、オープンソースプロフェッショナル向けのグローバルな認定基準およびキャリアサポート組織です。200,000人以上の認定保持者を擁する、世界初かつ最大のベンダー中立Linuxおよびオープンソース認定機関です。LPIは180か国以上で認定プロフェッショナルを擁し、複数の言語で試験を実施し、何百ものトレーニングパートナーを擁しています。

私たちの目的は、オープンソースの知識とスキルの認定資格を世界中からアクセスできるようにすることで、誰にとっても経済的で創造的な機会を可能にすることです。

  • LinkedIn
  • flogo-RGB-HEX-Blk-58 Facebook
  • Twitter
  • お問い合わせ
  • 個人情報とCookieポリシー

間違いを見つけたり、このページを改善したいですか? 私たちに知らせてください。.

© 1999–2023 The Linux Professional Institute Inc. All rights reserved.