目次にジャンプページナビゲーションにジャンプ: 前のページ[アクセスキーp]/次のページ[アクセスキーn]
documentation.suse.com / SUSE Linux Enterprise Serverマニュアル / 管理ガイド / 共通のタスク / BashとBashスクリプト
適用項目 SUSE Linux Enterprise Server 15 SP5

1 BashとBashスクリプト

今日、多数のユーザが、GNOMEなどのGUI(グラフィカルユーザインターフェース)を介してコンピュータを使用しています。GUIは多くの機能を提供していますが、自動タスクを実行する際には用途は限定されています。シェルはGUIを適切に補完するものです。この章では、シェル(ここではBashシェル)のいくつかの側面について概要を説明します。

1.1 シェルとは何か?

従来、Linuxシェルとは、Bash(Bourne again Shell)のことでした。この章では、Bashをシェルと呼びます。シェルはBashの他にもあり(ash、csh、ksh、zshなど)、異なる機能と特性を持っています。他のシェルの詳細については、YaSTで「シェル」を検索してください。

1.1.1 Bashの環境設定ファイル

シェルは、次のようにして呼び出すことができます。

  1. 対話型ログインシェル.  コンピュータへのログイン時に、--loginオプションを使用してBashを呼び出す場合か、SSHを使用してリモートコンピュータへログインする場合に使用します。

  2. 通常の対話型シェル.  xtermやkonsole、gnome-terminalなどのコマンドラインインタフェース(CLI)ツールの起動時には、通常、この形式を使用します。

  3. 非対話型シェル.  コマンドラインからシェルスクリプトを呼び出す場合に呼び出されます。

シェルによって読み込まれる設定ファイルは異なります。次のテーブルには、それぞれ、ログインシェル設定ファイルと非ログインシェル設定ファイルが示されています。

ヒント
ヒント

Bashは、実行されているシェルのタイプに応じて特定の順序で設定ファイルを検索します。詳細については、Bashのマニュアルページ(man 1 bash)を参照してください。見出しINVOCATIONを検索します。

表 1.1: ログインシェル用Bash設定ファイル

ファイル

説明

/etc/profile

このファイルは変更しないでください。変更しても、次の更新で変更内容が破棄される可能性があります。

/etc/profile.local

/etc/profileを拡張する場合は、このファイルを使用します。

/etc/profile.d/

特定プログラムのシステム全体にわたる設定ファイルを含みます。

~/.profile

ログインシェル用のユーザ固有の設定をここに挿入します。

ログインシェルは、表1.2「非ログインシェル用Bash設定ファイル」に示す設定ファイルも参照します。

表 1.2: 非ログインシェル用Bash設定ファイル

/etc/bash.bashrc

このファイルは変更しないでください。変更しても、次の更新で変更内容が破棄される可能性があります。

/etc/bash.bashrc.local

Bashのシステム全体にわたる変更を挿入する場合のみ、このファイルを使用します。

~/.bashrc

ユーザ固有の設定をここに挿入します。

また、Bashは複数のファイルを使用します。

表 1.3: Bash用特殊ファイル

ファイル

説明

~/.bash_history

入力したすべてのコマンドのリストを含みます。

~/.bash_logout

ログアウト時に実行されます。

~/.alias

よく使用されるコマンドのユーザ定義エイリアス。エイリアスの定義の詳細については、man 1 aliasを参照してください。

非ログインシェル

ユーザがシステムにログインするのをブロックする特殊なシェル(/bin/false/sbin/nologin)があります。ユーザがシステムにログインしようとすると、両方ともサイレントに失敗します。これはシステムユーザのセキュリティ対策として意図されたものですが、最新のLinuxオペレーティングシステムには、PAMやAppArmorなど、システムアクセスを制御するためのより効果的なツールがあります。

SUSE Linux Enterprise Serverのデフォルトでは、人間のユーザに/bin/bashを、システムユーザに/bin/falseまたは/sbin/nologinを割り当てます。歴史的な理由のため、nobodyユーザは/bin/bashを使用します。これは、システムユーザのデフォルトとして使用されていた最小限の特権を持つユーザであるためです。ただし、nobodyを使用することにより得られたわずかなセキュリティも、複数のシステムユーザが使用すると失われます。これを/sbin/nologinに変更できるはずです。それをテストする最も早い方法は、変更を行い、サービスやアプリケーションを中断させていないかどうかを確認することです。

次のコマンドを使用して、/etc/passwdで、すべてのユーザ、システム、および人間のユーザに割り当てられているシェルを一覧にします。出力は、システムのサービスおよびユーザによって異なります。

> sort -t: -k 7 /etc/passwd | awk -F: '{print $1"\t" $7}' | column -t
tux               /bin/bash
nobody            /bin/bash
root              /bin/bash
avahi             /bin/false
chrony            /bin/false
dhcpd             /bin/false
dnsmasq           /bin/false
ftpsecure         /bin/false
lightdm           /bin/false
mysql             /bin/false
postfix           /bin/false
rtkit             /bin/false
sshd              /bin/false
tftp              /bin/false
unbound           /bin/false
bin               /sbin/nologin
daemon            /sbin/nologin
ftp               /sbin/nologin
lp                /sbin/nologin
mail              /sbin/nologin
man               /sbin/nologin
nscd              /sbin/nologin
polkitd           /sbin/nologin
pulse             /sbin/nologin
qemu              /sbin/nologin
radvd             /sbin/nologin
rpc               /sbin/nologin
statd             /sbin/nologin
svn               /sbin/nologin
systemd-coredump  /sbin/nologin
systemd-network   /sbin/nologin
systemd-timesync  /sbin/nologin
usbmux            /sbin/nologin
vnc               /sbin/nologin
wwwrun            /sbin/nologin
messagebus        /usr/bin/false
scard             /usr/sbin/nologin

1.1.2 ディレクトリ構造

次のテーブルでは、Linuxシステムの最も重要な上位レベルディレクトリについて、短い概要を示します。それらのディレクトリおよび重要なサブディレクトリの詳細については、後続のリストを参照してください。

表 1.4: 標準的なディレクトリツリーの概要

ディレクトリ

目次

/

ルートディレクトリ(ディレクトリツリーの開始場所)。

/bin

システム管理者および通常ユーザの両者が必要とするコマンドなどの必須バイナリファイル。通常、Bashなどのシェルも含みます。

/boot

ブートローダの静的ファイル

/dev

ホスト固有のデバイスのアクセスに必要なファイル

/etc

ホスト固有のシステム設定ファイル

/home

システムにアカウントを持つすべてのユーザのホームディレクトリを格納します。ただし、rootのホームディレクトリは、/homeでなく、/rootにあります。

/lib

必須の共有ライブラリおよびカーネルモジュール

/media

リムーバブルメディアのマウントポイント

/mnt

ファイルシステムを一時的にマウントするためのマウントポイント

/opt

アドオンアプリケーションのソフトウェアパッケージ

/root

スーパーユーザrootのホームディレクトリ。

/sbin

必須のシステムバイナリ

/srv

システムで提供するサービスのデータ

/tmp

一時ファイルを格納するディレクトリ

/usr

読み込み専用データを含む第二階層

/var

ログファイルなどの可変データ

/windows

システムにMicrosoft Windows*とLinuxの両方がインストールされる場合のみ利用可能。Windowsデータを含みます。

次のリストでは、さらに詳しい情報を提供し、ディレクトリに含まれるファイルおよびサブディレクトリの例を示します。

/bin

rootと他のユーザの両者が使用できる基本的なシェルコマンドを含みます。これらのコマンドには、lsmkdircpmvrmおよびrmdirが含まれています。また、/binには、SUSE Linux Enterprise ServerのデフォルトシェルであるBashも含まれます。

/boot

ブートに必要なデータ(ブートローダやカーネルのデータなど)と、その他のデータ(カーネルがユーザモードプログラムの実行を開始する前に使用)が含まれます。

/dev

ハードウェアコンポーネントを記述したデバイスファイルを格納します。

/etc

X Window Systemなどのプログラムの動作を制御するローカル設定ファイルを含みます。/etc/init.dサブディレクトリは、ブートプロセスで実行できるLSB initスクリプトを含みます。

/home/USERNAME

システムにアカウントを持つすべてのユーザの個人データを格納します。このディレクトリ内のファイルは、その所有者またはシステム管理者しか変更できません。デフォルトでは、電子メールのディレクトリとパーソナルデスクトップの設定が、.gconf/.configなどの非表示のファイルおよびディレクトリとして、ここに格納されます。

注記
注記: ネットワーク環境でのホームディレクトリ

ネットワーク環境で作業するユーザのホームディレクトリは、/home以外のファイルシステム内のディレクトリにマップできます。

/lib

システムのブートとルートファイルシステムでのコマンドの実行に必要な必須共有ライブラリを含みます。Windowsで共有ライブラリに相当するものは、DLLファイルです。

/media

CD-ROM、フラッシュディスク、デジタルカメラ(USBを使用する場合)など、リムーバブルメディアのマウントポイントを含みます。/mediaでは、一般にシステムのハードディスク以外のあらゆるタイプのドライブが保持されます。リムーバブルメディアをシステムに挿入または接続し、マウントを完了すると、そのメディアにこのディレクトリからアクセスできます。

/mnt

このディレクトリは一時的にマウントされるファイルシステムのマウントポイントを提供します。rootはここにファイルシステムをマウントできます。

/opt

サードパーティのソフトウェアのインストール用に予約されています。オプションソフトウェアや大型アドオンプログラムのパッケージをここに格納できます。

/root

rootユーザのホームディレクトリ。rootの個人データがここに保存されます。

/run

systemdとさまざまなコンポーネントによって使用されるtmpfsディレクトリ。/var/runは、/runへのシンボリックリンクです。

/sbin

sで示唆されるように、このディレクトリはスーパーユーザ用のユーティリティを格納します。/sbinには、/bin内のバイナリとともにシステムのブート、復元、および回復に不可欠なバイナリが含まれます。

/srv

FTPやHTTPなど、システムによって提供されるサービスのデータを格納します。

/tmp

ファイルの一時的保管を必要とするプログラムによって使用されます。

重要
重要: ブート時の/tmpのクリーンアップ

/tmpに保存したデータは、システムのリブート後も残っているかは保証できません。データが残っているかどうかは、たとえば/etc/tmpfiles.d/tmp.confの設定によって異なります。

/usr

/usrは、ユーザとは無関係であり、UNIX system resourcesを意味する略語です。/usr内のデータは静的な読み込み専用データです。このデータは、FHS (Filesystem Hierarchy Standard)に準拠するホスト間で共有できます。このディレクトリは、GNOMEなどのグラフィカルデスクトップをはじめ、すべてのアプリケーションプログラムを含み、ファイルシステム内の第二階層を形成します。/usrには、/usr/bin/usr/sbin/usr/local/usr/share/docなどいくつかのサブディレクトリがあります。

/usr/bin

一般ユーザがアクセスできるプログラムを含みます。

/usr/sbin

修復関数など、システム管理者用に予約されたプログラムを含みます。

/usr/local

このディレクトリには、システム管理者がディストリビューションに依存しないローカルな拡張プログラムをインストールできます。

/usr/share/doc

システムのドキュメントファイルおよびリリースノートを格納します。manualサブディレクトリには、このマニュアルのオンラインバージョンが格納されます。複数の言語をインストールする場合は、このディレクトリに各言語のマニュアルを格納できます。

packagesには、システムにインストールされたソフトウェアパッケージに含まれているドキュメントが格納されます。パッケージごとに、サブディレクトリ/usr/share/doc/packages/PACKAGENAMEが作成されます。このサブディレクトリには、多くの場合、パッケージのREADMEファイルが含まれます。例、設定ファイル、または追加スクリプトが含まれる場合もあります。

HOWTOをシステムにインストールした場合は、/usr/share/dochowtoサブディレクトリも含まれます。このサブディレクトリには、Linuxソフトウェアの設定および操作に関する多数のタスクの追加ドキュメントが格納されます。

/var

/usrは静的な読み込み専用データを含みますが、/varは、システム動作時に書き込まれる可変データ(ログファイル、スプールデータなど)のディレクトリです。/var/log/にある重要なログファイルの概要は、表48.1「ログファイル」を参照してください。

1.2 シェルスクリプトの作成

シェルスクリプトは、データの収集、テキスト内のワードやフレーズの検索など、さまざまな有用なタスクの実行に便利な方法です。次の例では、小型のシェルスクリプトでテキストをプリントします。

例 1.1: テキストをプリントするシェルスクリプト
#!/bin/sh 1
# Output the following line: 2
echo "Hello World" 3

1

最初の行は、このファイルがスクリプトであることを示すShebang文字(#!)で始まります。Shebangの後に指定されたインタープリタによってスクリプトが実行されます。この場合、指定されたインタープリタは/bin/shです。

2

2行目は、ハッシュ記号で始まるコメントです。意図を理解しにくい行にはコメントすることをお勧めします。適切にコメントすると、行の目的および機能を覚えることができます。また、他の読み手もスクリプトをより良く理解できます。コメントは開発コミュニティにおいてグッドプラクティスとみなされます。

3

3番目の行で、組み込みコマンドechoを使用して、対応するテキストを出力します。

このスクリプトを実行するには、その前にいくつかの前提条件があります。

  1. すべてのスクリプトには(上記の例のように) Shebang行が含まれている必要があります。この行がない場合は、インタプリタを手動で呼び出す必要があります。

  2. スクリプトの保存場所はどこでも構いません。ただし、シェルの検索先ディレクトリを保存場所にすることをお勧めします。シェルのサーチパスは、環境変数PATHで設定されます。標準ユーザには/usr/binへの書き込みアクセスはありません。このため、スクリプトはユーザのディレクトリ~/bin/に保存することを推奨します。上記の例では、名前はhello.shです。

  3. スクリプトには、実行可能パーミッションが必要です。次のコマンドで、パーミッションを設定してください。

    > chmod +x ~/bin/hello.sh

これらの前提条件をすべて満たしたら、次の方法でスクリプトを実行できます。

  1. 絶対パス.  スクリプトは絶対パスで実行できます。この例では、~/bin/hello.shです。

  2. 任意の場所.  PATH環境変数にスクリプトが存在するディレクトリが含まれている場合、スクリプトをhello.shで実行できます。

1.3 コマンドイベントのリダイレクト

各コマンドは、入力または出力用として、3つのチャネルを使用できます。:

  • 標準出力.  デフォルトの出力チャネル。コマンドで何かをプリントする際には標準出力チャネルが使用されます。

  • 標準入力.  コマンドでユーザまたは他のコマンドからの入力を必要とする場合は、このチャネルが使用されます。

  • 標準エラー.  このチャネルは、エラーレポーティングに使用されます。

これらのチャネルをリダイレクトするには、次の方法を使用できます。

Command > File

コマンド出力をファイルに保存します。既存ファイルは削除されます。たとえば、lsコマンドの出力をlisting.txtファイルに書き込みます。

> ls > listing.txt
Command >> File

コマンド出力をファイルに追加します。たとえば、lsコマンドの出力をlisting.txtファイルに追加します。

> ls >> listing.txt
Command < File

ファイルを読み込み、指定されたコマンドへの入力とします。たとえば、ファイルのコンテンツをreadコマンドで読み込み、変数に入力します。

> read a < foo
Command1 | Command2

左側のコマンドの出力を右側のコマンドの入力にします。たとえば、catコマンドは、/proc/cpuinfoファイルの内容を出力します。この出力をgrepで使用して、cpuを含む行のみをフィルタします。

> cat /proc/cpuinfo | grep cpu

各チャネルには、対応するファイル記述子があります。標準入力には0(ゼロ)、標準出力には1、標準エラーには2が割り当てられています。このファイル記述子を<文字または>文字の前に挿入できます。たとえば、次の行では、fooで始まるファイルを検索しますが、そのファイルを/dev/nullにリダイレクトすることでエラーメッセージを抑制します。

> find / -name "foo*" 2>/dev/null

1.4 エイリアスの使用

エイリアスは、1つ以上のコマンドのショートカット定義です。エイリアスの構文は、次のとおりです。

alias NAME=DEFINITION

たとえば、次の行は、エイリアスltを定義しています。このエイリアスは、長いリストを出力し(-lオプション)、そのリストを変更時刻でソートし(-tオプション)、ソート順と逆の順序でプリントします(-rオプション)。

> alias lt='ls -ltr'

すべてのエイリアス定義を表示するには、aliasを使用します。unaliasで対応するエイリアス名を指定して、エイリアスを削除します。

1.5 Bashでの変数の使用

シェル変数は、グローバル変数またはローカル変数として使用できます。グローバル変数(つまり、環境変数)は、すべてのシェルでアクセスできます。対照的に、ローカル変数は、現在のシェルでのみアクセスできます。

すべての環境変数を表示するには、printenvコマンドを使用します。変数の値を知る必要がある場合は、変数の名前を引数として挿入します。

> printenv PATH

変数はグローバルでもローカルでも、echoで表示できます。

> echo $PATH

ローカル変数を設定するには、変数名の後に等号を入れ、その後に値を指定します。

> PROJECT="SLED"

等号の前後にスペースを挿入しないでください。スペースを挿入すると、エラーになります。環境変数を設定するには、exportを使用します。

> export NAME="tux"

変数を削除するには、unsetを使用します。

> unset NAME

次の表には、シェルスクリプトで使用できる一般的な環境変数が含まれています。

表 1.5: 便利な環境変数

HOME

現在のユーザのホームディレクトリ

HOST

現在のホスト名

LANG

ツールをローカライズする場合、ツールは、この環境変数からの言語を使用します。英語をCに設定することも可能です。

PATH

シェルのサーチパス。コロンで区切ったディレクトリのリスト

PS1

各コマンドの前にプリントされる通常のプロンプトを指定します。

PS2

複数行コマンドの実行時にプリントされるセカンダリプロンプトを指定します。

PWD

現在の作業ディレクトリ

USER

現在のユーザ

1.5.1 引数変数の使用

たとえば、スクリプトfoo.shは、次のように実行できます。

> foo.sh "Tux Penguin" 2000

スクリプトに渡される引数すべてにアクセスするには、位置パラメータが必要です。これらのパラメータは、最初の引数には$1、2つ目の引数には$2という順序で割り当てます。パラメータは最大9つまで使用できます。スクリプト名を取得するには、$0を使用します。

次のスクリプトfoo.shは、1から4までのすべての引数をプリントします。

#!/bin/sh
echo \"$1\" \"$2\" \"$3\" \"$4\"

このスクリプトを既出例の引数を使用して実行すると、次の結果が出力されます。

"Tux Penguin" "2000" "" ""

1.5.2 変数置換の使用

変数置換では、変数のコンテンツに、左側または右側からパターンを適用します。次のリストに、可能な構文形式を示します。

${VAR#pattern}

左側から最も短い一致を削除します。

> file=/home/tux/book/book.tar.bz2
> echo ${file#*/}
home/tux/book/book.tar.bz2
${VAR##pattern}

左側から最も長い一致を削除します。

> file=/home/tux/book/book.tar.bz2
> echo ${file##*/}
book.tar.bz2
${VAR%pattern}

右側から最も短い一致を削除します。

> file=/home/tux/book/book.tar.bz2
> echo ${file%.*}
/home/tux/book/book.tar
${VAR%%pattern}

右側から最も長い一致を削除します。

> file=/home/tux/book/book.tar.bz2
> echo ${file%%.*}
/home/tux/book/book
${VAR/pattern_1/pattern_2}

VARのコンテンツをPATTERN_1からPATTERN_2に置換します。

> file=/home/tux/book/book.tar.bz2
> echo ${file/tux/wilber}
/home/wilber/book/book.tar.bz2

1.6 コマンドのグループ化と結合

シェルでは、条件付き実行のため、コマンドを結合し、グループ化することができます。各コマンドが返す終了コードにより、コマンドの成功または失敗が判別されます。終了コードが0(ゼロ)の場合、コマンドは成功しました。それ以外はすべて、コマンド固有のエラーをマークします。

次に、コマンドをグループ化する方法を示します。

Command1 ; Command2

コマンドをシーケンシャルに実行します。終了コードはチェックされません。次の行では、各コマンドの終了コードにかかわらず、catでファイルのコンテンツを表示し、次に、lsでファイルプロパティをプリントします。

> cat filelist.txt ; ls -l filelist.txt
Command1 && Command2

左のコマンドが成功した場合、右のコマンドを実行します(論理AND)。次の行では、ファイルのコンテンツを表示し、そのコマンドが成功した場合のみ、ファイルのプロパティをプリントします(このリストの前の項目と比較してください)。

> cat filelist.txt && ls -l filelist.txt
Command1 || Command2

左のコマンドが失敗した場合、右のコマンドを実行します(論理OR)次の行では、/home/tux/fooでのディレクトリ作成に失敗した場合のみ、/home/wilber/bar内にディレクトリを作成します。

> mkdir /home/tux/foo || mkdir /home/wilber/bar
funcname(){ ... }

シェル関数を作成します。位置パラメータを使用して、関数の引数にアクセスできます。次の行では、短いメッセージをプリントする関数helloを定義します。

> hello() { echo "Hello $1"; }

この関数は、次のように呼び出せます。

> hello Tux

結果は、次のようにプリントされます。

Hello Tux

1.7 よく使用されるフローコンストラクトの操作

スクリプトのフローを制御するため、シェルでは、whileifforおよびcaseの各構文を使用します。

1.7.1 if制御コマンド

ifコマンドは、式のチェックに使用されます。たとえば、次のコードは、現在のユーザがTuxであるかどうかをテストします。

if test $USER = "tux"; then
  echo "Hello Tux."
else
  echo "You are not Tux."
fi

テスト式は、複雑にすることも、シンプルにすることも可能です。次の式は、ファイルfoo.txtが存在するかどうかをチェックします。

if test -e /tmp/foo.txt ; then
  echo "Found foo.txt"
fi

test式は、角括弧で短縮することもできます。

if [ -e /tmp/foo.txt ] ; then
  echo "Found foo.txt"
fi

その他の役に立つ式については、https://bash.cyberciti.biz/guide/If..else..fiを参照してください。

1.7.2 forコマンドによるループの作成

forループを使用すると、エントリのリストにコマンドを実行できます。たとえば、次のコードは、現在のディレクトリ内のPNGファイルの特定の情報をプリントします。

for i in *.png; do
 ls -l $i
done

1.8 詳細情報

Bashに関する重要な情報は、マニュアルページman bashに記載されています。このトピックの詳細については、次のリストを参照してください。