目次


Linux の 101 試験対策

シェル環境のカスタマイズと使用

ユーザーのニーズを満たす

Comments

コンテンツシリーズ

このコンテンツは全#シリーズのパート#です: Linux の 101 試験対策

このシリーズの続きに乞うご期待。

このコンテンツはシリーズの一部分です:Linux の 101 試験対策

このシリーズの続きに乞うご期待。

概要

このチュートリアルでは、ユーザーのニーズを満たすように Linux bash シェル環境をカスタマイズする方法を学びます。このチュートリアルで説明する内容は以下のとおりです。

  • グローバル・プロファイルとユーザー・プロファイルを変更する方法
  • ログイン時または新しいシェルを生成したときに環境変数を設定する方法
  • 頻繁に使用するコマンド・シーケンスに対応する bash 関数を作成する方法
  • 新しいユーザー・アカウント用のスケルトン・ディレクトリーを保守する方法
  • コマンド検索パスを設定する方法

Linux シェル

Linux シェル・プログラムを使用してシステムを操作するには、ターミナル・ソフトでコマンド (「入力ストリーム」) を入力して、出力 (「出力ストリーム」) やエラー・メッセージ (「エラー・ストリーム」) を確認します。ときには、ターミナル接続が十分可能になるところまでシステムのブートが完了する前に、コマンドを実行する必要がある場合や、ログインしているかどうかに関わらず定期的にコマンドを実行する必要がある場合があります。シェルは、こうした作業を皆さんに代わって実行することもできます。標準入力/出力ストリームは、ターミナルの実際のユーザーが送信元または送信先でなければないわけではありません。このチュートリアルでは、シェルに関する詳細と、ユーザーのシェル環境をカスタマイズする方法を取り上げます。具体的には、最初に作られた Bourne シェルの機能強化版である bash (Bourne again) シェルと、bash を POSIX (Portable Operating System Interface) により準拠したものにするための変更について説明します。その過程で、他のシェルの機能についても目を向けます。

このチュートリアルは、LPIC-1: Linux Server Professional Certification 102 試験における主題 105 の項目 105.1 に備える上で役に立ちます。この項目は、重要度が 4 とされています。

前提条件

この連載のチュートリアルを最大限に活用するには、Linux の基礎知識と、チュートリアルに記載されたコマンドを演習できる実際の Linux システムが必要です。また、GNU コマンドと UNIX コマンドの知識もなければなりません。このチュートリアルは、101 試験の主題 103 を対象としたチュートリアルの内容をベースにしています。プログラムのバージョンによって出力のフォーマットに違いが出てくる場合もあるため、コマンドの実行結果は必ずしもここに記載するリストや図とまったく同じであるとは限りません。

このチュートリアルに記載する例の大半は、ディストリビューションに依存しません。特に断りのない限り、記載する例ではカーネル 4.2.3 を搭載した Fedora 22 を使用しています。

シェルと環境

シェルは、複雑なオペレーティング・システムと、ユーザーとの間に位置するレイヤーとなります。Linux (および UNIX) のシェルでは、基本的な関数を組み合わせることで、複雑な操作を作成することができます。プログラミング構成体を使用すれば、シェル内で直接実行する関数を作成することや、関数を「シェル・スクリプト」として保存することができます。シェル・スクリプトとは、必要に応じてシェルで実行できる、ファイルに保存された一連のコマンドのことです。

POSIX とは、総称して IEEE 1003 と呼ばれる、一連の IEEE 標準のことです (最初の POSIX 標準は、1988年にリリースされた IEEE 標準 1003.1-1988 です)。多くの POSIX 機能を実装する bash は、POSIX に極めて準拠したモードで実行することができます。その他のよく知られているシェルには、Korn シェル (ksh)、C シェル (csh) およびそこから派生した tcsh、Almquist シェル (ash) およびそこから派生した Debian (dash) があります。このいずれかのシェルの機能をスクリプトで使用しているときに、少なくともどのシェルを使用しているかを認識できるだけの知識を身に付けておくことをお勧めします。

チュートリアル「Linux の 101 試験対策: Linux コマンドライン」で説明したように、bash シェルの実行中には、「シェル環境」が構成されます。この環境は、プロンプトのフォーム、ホーム・ディレクトリー、作業ディレクトリー、シェルの名前、開いているファイル、定義した関数、その他多数の要素を定義する、一連の名前と値のペアで構成され、すべてのシェル・プロセスで有効になります。シェルは起動時に、シェル環境に含まれる値を「シェル変数」に代入します。bash をはじめとするシェルを使用して、シェル変数を追加で作成することや、変更することができます。作成または変更したそれらの変数は、現在のシェルから生成された子プロセスが継承する環境に含まれるように、エクスポートすることができます。

シェル変数には名前 (識別子) があります。表 1 に、一般的な bash 環境変数の一部を記載します。通常、これらの変数は自動的に設定されます。

表 1. 一般的な bash 環境変数
名前目的
USERログイン済みユーザーの名前
UIDログイン済みユーザーの数値によるユーザー ID
HOMEユーザーのホーム・ディレクトリー
PWD現在の作業ディレクトリー
SHELLシェルの名前
PPID親プロセスの PID — そのプロセスを開始したプロセスのプロセス ID

シェルには変数の他に、設定されるけれども変更できない特殊なパラメーターがいくつかあります。表 2 にいくつかの例を記載します。

表 2. 一般的な bash パラメーター
名前目的
$プロセス ID (実行中の bash シェル (またはその他の) プロセスの PID)
?最後のコマンドの終了コード
0シェルまたはシェル・スクリプトの名前

変数を使用する

変数の値を使用するには、その変数の名前の先頭に「$」を追加します (リスト 1 を参照)。

リスト 1. 変数の値を使用する
[ian@atticf22 ~]$ echo $UID
1000
[ian@atticf22 ~]$ echo $HOME
/home/ian

変数の値を設定して、それらの値を使用可能にする

bash シェルでシェル変数を作成または設定するには、変数名の直後に、スペースを入れずに等号 (=) を入力します。変数名は、英数字とアンダーバーだけからなる単語です。変数名は英字またはアンダーバーで始まります。変数名では大文字/小文字が区別されるため、var1VAR1 はそれぞれ別個の変数となります。表 1 の例に示されているように、変数名は多くの場合 (特にエクスポートされた変数の場合は)、大文字ですが、変数名を大文字にするのは慣例であり、要件ではありません。変数のなかには、変数というよりも実際にはシェル・パラメーターとして機能するものがあります ($$$? など)。 — このような変数は参照することしかできず、値を代入することはできません。

シェル変数は、それらの変数を作成したプロセスからしか見えません。ただし、シェル変数を「エクスポート」することで、子プロセスからシェル変数が見えるようにして、使えるようにした場合は別です。子プロセスが親プロセスに変数をエクスポートすることはできません。変数をエクスポートするには export コマンドを使用します。bash シェルでは変数の代入とエクスポートを 1 つのステップで行うことができますが、この機能はすべてのシェルでサポートされているわけではありません。

これらの概念を調べるのに適した方法は、別のシェルを使用して子プロセスを作成することです。また、どこで何を実行しているかを追跡する上で役立つコマンドとして、ps コマンドを使用することができます。皆さんの役に立つように、いくつかの例をインライン・コメント付きでリスト 2 に示します。

リスト 2. シェル変数を設定して環境にエクスポートする
[ian@atticf22 ~]$ # Use the ps command to list current PID, parent PID and running command name
[ian@atticf22 ~]$ ps -p $$ -o "pid ppid cmd"
  PID  PPID CMD
12761  9169 bash
[ian@atticf22 ~]$ # Start a child bash process
[ian@atticf22 ~]$ bash
[ian@atticf22 ~]$ # Assign two variables
[ian@atticf22 ~]$ VAR1=v1
[ian@atticf22 ~]$ VAR2="Variable 2"
[ian@atticf22 ~]$ # Export examples
[ian@atticf22 ~]$ export VAR2
[ian@atticf22 ~]$ export VAR3="Assigned and exported in one step"
[ian@atticf22 ~]$ # Use the $ character to reference the variables
[ian@atticf22 ~]$ echo $VAR1 '/' $VAR2 '/' $VAR3
v1 / Variable 2 / Assigned and exported in one step
[ian@atticf22 ~]$ # What is the value of the SHELL variable?
[ian@atticf22 ~]$ echo $SHELL
/bin/bash
[ian@atticf22 ~]$ # Now start ksh child and export VAR4
[ian@atticf22 ~]$ ksh
$ ps -p $$ -o "pid ppid cmd"
  PID  PPID CMD
26212 22923 ksh
$ export VAR4=var4
$ # See what is visible
$ echo $VAR1 '/' $VAR2 '/' $VAR3 '/' $VAR4 '/' $SHELL
/ Variable 2 / Assigned and exported in one step / var4 / /bin/bash
$ # No VAR1 and shell is /bin/bash - is that right?
$ exit
[ian@atticf22 ~]$ ps -p $$ -o "pid ppid cmd"
  PID  PPID CMD
22923 12761 bash
[ian@atticf22 ~]$ # See what is visible
[ian@atticf22 ~]$ echo $VAR1 '/' $VAR2 '/' $VAR3 '/' $VAR4 '/' $SHELL
v1 / Variable 2 / Assigned and exported in one step / / /bin/bash
[ian@atticf22 ~]$ # No VAR4 - our child cannot export back to us
[ian@atticf22 ~]$ exit
exit
[ian@atticf22 ~]$ ps -p $$ -o "pid ppid cmd"
  PID  PPID CMD
12761  9169 bash
[ian@atticf22 ~]$ # See what is visible
[ian@atticf22 ~]$ echo $VAR1 '/' $VAR2 '/' $VAR3 '/' $VAR4 '/' $SHELL
/ / / / /bin/bash
[ian@atticf22 ~]$ # None of VAR1 through VAR4 is exported back to parent

このリスト 2 では、ksh は SHELL 変数を設定していなかったことに気付きましたか?この変数は通常、ユーザーがログインしたとき、または別のユーザーに切り替える su コマンドで「ログイン・シェル」を作成するオプションを指定したときに、設定されます。ログイン・シェルについては、このチュートリアルで後から詳しく説明します。

表 1表 2 に記載されている bash の一般的な変数とパラメーターの中には、以下のリスト 3 に示すように echo コマンドを使用することで、その設定値を確認できるものがあります。

リスト 3. 一般的な環境変数とシェル変数
[ian@atticf22 ~]$ echo $USER $UID
ian 1000
[ian@atticf22 ~]$ echo $SHELL $HOME $PWD
/bin/bash /home/ian /home/ian
[ian@atticf22 ~]$ (exit 0);echo $?;(exit 4);echo $?
0
4

[ian@atticf22 ~]$ echo $0
bash
[ian@atticf22 ~]$ echo $$ $PPID
12761 9169
[ian@atticf22 ~]$ # see what my process and its parent are running
[ian@atticf22 ~]$ ps -p $$,$PPID -o "pid ppid cmd"
  PID  PPID CMD
 9169 1 /usr/libexec/gnome-terminal-server
12761  9169 bash

bash シェルでは、1 つのコマンドが実行されている間だけ有効な環境値を設定することもできます。それにはリスト 4 に示すように、コマンドの先頭に <名前>=<値> のペアを追加します。

リスト 4. 1 つのコマンドを対象とした bash 環境値を設定する
[ian@atticf22 ~]$ echo "$VAR5 / $VAR6"
 / 
[ian@atticf22 ~]$ VAR5=5 VAR6="some value" bash
[ian@atticf22 ~]$ echo "$VAR5 / $VAR6"
5 / some value
[ian@atticf22 ~]$ exit
[ian@atticf22 ~]$ echo "$VAR5 / $VAR6"
 /

readonly 属性とその他の変数属性

前述したように、シェル・パラメーターの中には変更できないものがあります。それとは別に、変数を readonlyintegerstring などに制約することもできます。これらの変数属性を設定するには、declare コマンドを使用します。-p オプションを指定すると、変数がさまざまな属性と一緒に表示されます。declare コマンドの詳細を調べるには、以下のコマンドを実行します。

info bash "Shell Builtin Commands" "Bash Builtins"  --index-search declare

or

help declare

または以下のコマンドで調べることもできます。

リスト 5 に例をいくつか記載します。
[ian@atticf22 ~]$ declare -r rov1="this is readonly"
[ian@atticf22 ~]$ rov="Who says it's read only?"
[ian@atticf22 ~]$ readonly rov2="another constant value"
[ian@atticf22 ~]$ rov2=3
bash: rov2: readonly variable
[ian@atticf22 ~]$ UID=99
bash: UID: readonly variable
[ian@atticf22 ~]$ declare -pr
declare -r BASHOPTS="checkwinsize:cmdhist:complete_fullquote:expand_aliases:extglob:extquote:
force_fignore:histappend:interactive_comments:progcomp:promptvars:sourcepath"
declare -ir BASHPID
declare -r BASH_COMPLETION_COMPAT_DIR="/etc/bash_completion.d"
declare -ar BASH_VERSINFO='([0]="4" [1]="3" [2]="42" [3]="1" [4]="release" [5]=
"x86_64-redhat-linux-gnu")'
declare -ir EUID="1000"
declare -ir PPID="12761"
declare -r SHELLOPTS="braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor"
declare -ir UID="1000"
declare -r rov1="this is readonly"
declare -r rov2="another constant value"
[ian@atticf22 ~]$ help declare
declare: declare [-aAfFgilnrtux] [-p] [name[=value] ...]
    Set variable values and attributes.
    
    Declare variables and give them attributes.  If no NAMEs are given,
    display the attributes and values of all variables.
    
    Options:
      -f   restrict action or display to function names and definitions
      -F   restrict display to function names only (plus line number and
       source file when debugging)
      -g   create global variables when used in a shell function; otherwise
       ignored
      -p   display the attributes and value of each NAME
    
    Options which set attributes:
      -a   to make NAMEs indexed arrays (if supported)
      -A   to make NAMEs associative arrays (if supported)
      -i   to make NAMEs have the `integer' attribute
      -l   to convert NAMEs to lower case on assignment
      -n   make NAME a reference to the variable named by its value
      -r   to make NAMEs readonly
      -t   to make NAMEs have the `trace' attribute
      -u   to convert NAMEs to upper case on assignment
      -x   to make NAMEs export
    
    Using `+' instead of `-' turns off the given attribute.
    
    Variables with the integer attribute have arithmetic evaluation (see
    the `let' command) performed when the variable is assigned a value.
    
    When used in a function, `declare' makes NAMEs local, as with the `local'
    command.  The `-g' option suppresses this behavior.
    
    Exit Status:
    Returns success unless an invalid option is supplied or a variable
    assignment error occurs.

Unsetting variables

bash シェルから変数を削除するには、unset コマンドを使用します。-v オプションを指定することで、変数定義が削除されることが確実になります。関数 (このチュートリアルで後ほど説明します) には変数と同じ名前を使用できるため、関数定義を削除する場合は -f を指定します。bash の unset コマンドに -f-v がどちらも指定されていない場合には、変数定義が存在する場合は変数定義を削除し、変数定義が存在せず、関数定義が存在する場合は関数定義を削除します。リスト 6 に例をいくつか記載します。

リスト 6. bash 変数を設定解除する
[ian@atticf22 ~]$ bash
[ian@atticf22 ~]$ VAR1=v1
[ian@atticf22 ~]$ declare -i VAR2
[ian@atticf22 ~]$ VAR2=3+4
[ian@atticf22 ~]$ echo $VAR1 $VAR2
v1 7
[ian@atticf22 ~]$ unset VAR1
[ian@atticf22 ~]$ echo $VAR1 $VAR2
7
[ian@atticf22 ~]$ unset -v VAR2
[ian@atticf22 ~]$ echo $VAR1 $VAR2

[ian@atticf22 ~]$ exit
exit

変数が integer として定義されている場合、変数への代入は演算式として評価されることに注意してください。

デフォルトでは、bash は設定解除された変数を、あたかもそれらの変数が空の値を持つかのように扱います。そうであれば、なぜ空の値を代入するのではなく、変数を設定解除するのでしょう?それは、bash やその他多数のシェルでは、未定義の変数が参照されている場合にエラーを生成することができるからです。set -u コマンドを使用すると、未定義の変数に対してエラーが生成され、set +u を使用するとその警告が無効になります。リスト 7 にこれらの点をまとめて示します。

リスト 7. エラーと設定解除された変数
[ian@atticf22 ~]$ bash
[ian@atticf22 ~]$ set -u
[ian@atticf22 ~]$ VAR1=var1
[ian@atticf22 ~]$ echo $VAR1
var1
[ian@atticf22 ~]$ unset VAR1
[ian@atticf22 ~]$ echo $VAR1
bash: VAR1: unbound variable
[ian@atticf22 ~]$ VAR1=
[ian@atticf22 ~]$ echo $VAR1

[ian@atticf22 ~]$ unset VAR1
[ian@atticf22 ~]$ echo $VAR1
bash: VAR1: unbound variable
[ian@atticf22 ~]$ unset -v VAR1
[ian@atticf22 ~]$ set +u
[ian@atticf22 ~]$ echo $VAR1

[ian@atticf22 ~]$ exit
exit

ご覧のように、存在しない変数に対して設定解除を行ってもエラーにはなりません。それは、set -u が指定されている場合でも同じです。

環境、変数、C シェル

csh シェルと tcsh シェルにおける環境と変数の扱い方は、bash とは少し異なっており、これらのシェルで変数を設定するには set コマンドを使用し、変数を設定してエクスポートするには setenv コマンドを使用します。その場合のコマンドの構文は、リスト 8 に示すように bash の export コマンドの構文とはわずかに異なります。set を使用するときには、等号 (=) に注意してください。

リスト 8. C シェルおよび tcsh シェルで変数と環境値を設定する
[ian@atticf22 ~]$ tcsh
[ian@atticf22 ~]$ setenv E1 "Env variable 1"
[ian@atticf22 ~]$ set V2="variable 2"
[ian@atticf22 ~]$ echo "$E1 / $V2"
Env variable 1 / variable 2
[ian@atticf22 ~]$ tcsh
[ian@atticf22 ~]$ echo $E1
Env variable 1
[ian@atticf22 ~]$ echo $V2
V2: Undefined variable.
[ian@atticf22 ~]$ echo "$?E1 / $?V2"
1 / 0
[ian@atticf22 ~]$ exit

2 番目の tcsh シェルは、V2 変数を継承していないことに注意してください。V2 を参照しようとすると、bash で set -u が設定されている場合と同様にエラーが発生します。csh および tcsh では、NAME が設定されているかどうかを調べるために、$?NAME 構成体を使用することができます。この構成体は、NAME が設定されていれば 1 を返し、そうでなければ 0 を返します。

環境の扱い方におけるもう 1 つの違いとして、csh と tcsh では、変数と環境値に別個の名前空間を保持します。もし、変数用の名前空間と環境値用の名前空間で、同じ名前が出現した場合には、変数の定義の方が優先されます。bash の場合と同じく、変数を設定解除するには unset コマンドを使用します。一方、環境値を設定解除する場合は unsetenv コマンドを使用します。リスト 9 に、これらのコマンドを使用している様子を示します。

リスト 9. csh と tcsh の変数および環境値を設定解除する
[ian@atticf22 ~]$ echo "$E1 / $V2"
Env variable 1 / variable 2
[ian@atticf22 ~]$ set E1="I'm now a regular variable"
[ian@atticf22 ~]$ echo $E1
I'm now a regular variable
[ian@atticf22 ~]$ unset E1
[ian@atticf22 ~]$ echo $E1
Env variable 1
[ian@atticf22 ~]$ unsetenv E1
[ian@atticf22 ~]$ echo $E1
E1: Undefined variable.

プロファイル・ファイル

ユーザーが Linux システムにログインすると、そのユーザー ID に対してデフォルトのシェルが設定されます。このシェルが、そのユーザーの「ログイン・シェル」です。シェル・プログラムは、/etc/passwd ファイル内のエントリーとして指定され、SHELL 環境変数を設定するために、このエントリーの値が使用されます。/etc/passwd ファイルの詳細を調べるには、man  5  passwd コマンドを使用します。

ユーザーのログイン・シェルが bash である場合、ユーザーに制御が渡される前に、bash によっていくつかのプロファイル・スクリプトが実行されます。/etc/profile が存在する場合は、bash は最初に /etc/profile.d 内のあらゆる .sh ファイルと併せて、/etc/profile を実行します。bash はシステム・スクリプトを実行した後、ユーザーのホーム・ディレクトリーで ~/.bash_profile ファイル、~/.bash_login ファイル、~/.profile ファイルの有無をこの順番で調べ、最初に見つけたファイルを実行します。

/etc 内にあるディストリビューション・ファイル (/etc/profile など) はシステム・アップデートによって変更される可能性があるため、直接編集しないでください。システム上のすべてのユーザーを対象にログイン環境をカスタマイズする必要がある場合には、ディストリビューション・ファイルを直接編集するのではなく、/etc/profile.d 内に追加のファイルを作成します。言うまでもなく、ホーム・ディレクトリー内のファイルは、個々のユーザーそれぞれの作業スタイルに合わせて変更することができます。

ログインして bash を使用していると、おそらくさらなるシェルを起動してコマンドを実行するようになるはずです。シェルがキーボードからのコマンドを受け付ける場合、それは「対話型」シェルです。シェルの入力がファイルから提供されるとしたら、それは「非対話型」シェルです。対話型シェルの場合、bash は ~/.bashrc スクリプトが存在すれば、そのスクリプトを実行します。~/.bash_profile 内でこのスクリプトの有無をチェックするのは慣例となっているため、ログイン時および対話型シェルを起動する際にこのスクリプトを実行することができます。ディストリビューションによっては、ユーザーの ~/.bashrc は、/etc/bash.bashrc または /etc/bashrc から共通のエイリアスとグローバル変数を入手することができます。ユーザーのホーム・ディレクトリーに ~/.bash_logout スクリプトが存在する場合、bash はユーザーがログオフする際には、このスクリプトを実行します。リスト 10 に、私の .bash_profile を示します。

リスト 10. 私の .bash_profile
[ian@atticf22 ~]$ cat ~/.bash_profile 
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
   . ~/.bashrc
fi

# User specific environment and startup programs

PATH=$PATH:$HOME/.local/bin:$HOME/bin

export PATH

--login オプションを指定すると、あたかも bash がログイン・シェルであるかのように、bash はプロファイルを読み取るようになります。--noprofile オプションを指定すると、プロファイルをスキップするよう bash に対して指示がされます。同様に、--norc オプションを指定すると、対話型シェルでの ~/.bashrc ファイルの実行が無効になります。bash に ~/.bashrc 以外のファイルを使用させるには、使用するファイル名を --rcfile オプションで指定します。リスト 11 に、--rcfile オプションで使用する、単純なサンプル・ファイルを作成する方法を示します。

リスト 11. --rcfile パラメーターでファイルを指定して使用する
[ian@atticf22 ~]$ echo VAR1=var1>testrc
[ian@atticf22 ~]$ echo $VAR1

[ian@atticf22 ~]$ bash --rcfile testrc
bash-4.3$ echo $VAR1
var1
bash-4.3$ exit
exit

キー・バインディング

bash を含め、多くのプログラムでは readline ライブラリーを使用してキーボードからのコマンドを読み取ります。キーストロークやキーの組み合わせを解釈する方法をカスタマイズするには、bash の組み込みコマンド bind を使用します。例えば、bind '"\C-t":"pwd\n"' は、pwd コマンドを実行するように Ctrl-t (Ctrl と t を一緒に押す) をバインドします。

デフォルト・キー・バインディングのグローバル・ファイルは /etc/inputrc です。独自のバインディングは、ホーム・ディレクトリー内の .inputrc ファイル内に作成することができます。その場合、以下の行を含めて、グローバル定義が除外されないようにしてください。

$include /etc/inputrc

See the bash info pages for more information.

bash を起動するその他の方法

ログイン・シェルと対話型シェルの起動方法については、既に説明しました。シェル・スクリプトを実行すると、bash はそのスクリプトを非対話型シェルで開始するため、プロファイル・ファイルは読み込まれません。ただし、BASH_ENV 変数が設定されている場合、bash はこの変数の値を展開し、その値がファイルの名前であることを前提にします。そのファイルが存在すれば、bash はユーザーが非対話型シェルでスクリプトやコマンドを実行する前に、そのファイルを実行します。リスト 12 に、この動作を示します。

リスト 12. BASH_ENV を使用する
[ian@atticf22 ~]$ cat testenv.sh
#!/bin/bash
echo "Test of BASH_ENV"
export VAR_ENV="my value"
[ian@atticf22 ~]$ cat testscript.sh
#!/bin/bash
echo "Running $0"
echo "VAR_ENV is set to $VAR_ENV"
[ian@atticf22 ~]$ ./testscript.sh
Running ./testscript.sh
VAR_ENV is set to 
[ian@atticf22 ~]$ export BASH_ENV="~/testenv.sh"
[ian@atticf22 ~]$ ./testscript.sh
Test of BASH_ENV
Running ./testscript.sh
VAR_ENV is set to my value

スクリプトが子シェルで実行される場合、そのスクリプトがエクスポートする変数は、親シェルに戻った時点ですべて失われますが、そうだとすれば .bash_profile が ~/.bashrc スクリプトを実行する場合には、~/.bashrc からエクスポートされる変数と関数が失われないのはどうしてなのでしょう?その答えは、ユーザーは現在の環境で source (または .) コマンドを使用してスクリプトを実行するからです。一例として、リスト 10 をもう一度見てください。

POSIX については前に触れましたが、bash をより POSIX に準拠したものにするには、--posix オプションを指定して bash を起動します。POSIX への準拠レベルがさまざまに異なる複数のシステムで機能するコードを開発しようとする場合には、このオプションを指定して bash を起動することになるでしょう。POSIX モードでの起動は、非対話型シェルの起動と同様ですが、実行する初期ファイル (初期ファイルが存在する場合) は BASH_ENV 変数ではなく ENV 変数によって決まります。

Linux システムでは、大抵は /bin/sh を bash へのシンボリック・リンクとして使用します。bash は sh という名前の下で自身が実行されていることを検出すると、POSIX 標準に準拠しながらも、かつての Bourne シェルの起動動作に従おうとします。ログイン・シェルとして実行される bash は、/etc/profile と ~/.profile を読み取って実行しようとします。sh コマンドによって対話型シェルとして実行される bash は、POSIX モードで呼び出された場合と同じく、ENV 変数で指定されたファイルを実行しようとします。非対話形式で sh として実行される bash は、ENV 変数で指定されたファイルだけを使用します。つまり、--rcfile オプションは無視されます。

最後に、リモート・シェル・デーモンによって呼び出された bash は、~/.bashrc ファイル (同ファイルが存在する場合) を使用して対話型シェルとして動作します。

パイプラインとコマンド・リスト

エイリアスと関数に話題を移す前に、パイプラインとコマンド・シーケンス (またはコマンド・リスト) についてしっかり理解しておく必要があります。パイプについて復習するには「Linux の 101 試験対策: ストリーム、パイプ、リダイレクト」を参照してください。コマンド・リストあるいはコマンド・シーケンスについて復習するには、と「Linux の 101 試験対策: Linux コマンドライン」を参照してください。

場合によっては、パイプラインのあるステージで複数のコマンドを 1 つのグループにまとめてから、それらすべてのコマンドの出力をパイプラインの次のステージにリダイレクトしなければならないことがあります。その場合、括弧を使用してコマンド・リストをサブシェルで実行することや、波括弧を使用してコマンド・リストを現在のシェルで実行することができます。波括弧についてはホワイト・スペースを使って他の要素から分離する必要がありますが、括弧は演算子として認識されるため、分離する必要はありません。リスト 13 ではこの 2 つの手法を使用して、/usr/bin 内の最大サイズのファイルを検出し、/usr/bin ディレクトリーが使用している合計スペースを表示します。

リスト 13. 括弧と波括弧によるコマンドのグループ化
[ian@atticf22 ~]$ (ls -lrS /usr/bin; du /usr/bin) | tail -n 3
-rwxr-xr-x.   1 root root    10669512 Sep 18 10:41 mysql
-rwxr-xr-t.   1 root root    15148768 Sep 14 05:11 emacs-24.5
386296   /usr/bin
[ian@atticf22 ~]$ { ls -lrS /usr/bin; du /usr/bin; } | tail -n 3
-rwxr-xr-x.   1 root root    10669512 Sep 18 10:41 mysql
-rwxr-xr-t.   1 root root    15148768 Sep 14 05:11 emacs-24.5
386296   /usr/bin

シェルでのエイリアス

bash では、コマンドのエイリアスを定義することができます。コマンドに代わりの名前を付ける場合や、コマンドのデフォルト・パラメーターを指定する場合には、エイリアスを使用します。さらに、新しいコマンドやより複雑なコマンドを作成するために、エイリアスを使用することもあります。エイリアスを設定したり、エイリアスを一覧表示したりするには、alias コマンドを使用し、エイリアスを削除するには、unalias コマンドを使用します。リスト 14 に例をいくつか記載します。

リスト 14. alias コマンドおよび unalias コマンドの単純な使用法
[ian@atticf22 ~]$ # Two commonly set aliases
[ian@atticf22 ~]$ alias ls ll
alias ls='ls --color=auto'
alias ll='ls -l --color=auto'
[ian@atticf22 ~]$ # Add one for a long listing in reverse chronological order
[ian@atticf22 ~]$ alias llrt='ls -lrt --color=auto'
[ian@atticf22 ~]$ llrt /bin
lrwxrwxrwx. 1 root root 7 Aug 16  2014 /bin -> usr/bin
[ian@atticf22 ~]$ # Remove our new alias
[ian@atticf22 ~]$ unalias llrt
[ian@atticf22 ~]$

図 1 に示すリスト 12 のテキストのスクリーンショットでは、新しい llrt コマンドのエイリアスの出力が色分けして示されています。

図 1. 色分けされた llrt コマンドの出力
前のリストのテキストを示す、色分けされた画面のスクリーンショット
前のリストのテキストを示す、色分けされた画面のスクリーンショット

bash でのエイリアス展開は、コマンドの最初の単語 (その単語が引用符で囲まれていない場合) に対して行われます。展開した最初の単語が、引用符で囲まれていない、まだ展開されていない単語であれば、bash は再びエイリアス展開を行うといった具合です。従って、llrt のエイリアスが alias  llrt='ls  -lrt であることもあれば、llrt のエイリアスが --color=auto パラメーター—を省略することもあります。どちらのエイリアスも、単語 ls に対してさらなる置き換えが行われるからです。これらのエイリアスや他のバリエーションを試してみてください。

エイリアスは、root ユーザーに対してもよく使用されます。cprmmv の各コマンドには通常、誤ってファイルが壊されることがないように、-i パラメーターを含めてエイリアスが設定されます。これらのコマンドのエイリアスを、ご使用のシステムで調べてください。

最後のより複雑な例として、リスト 15 に示す、which コマンドのエイリアスを定義する方法を見てください。

リスト 15. which コマンドのエイリアス
[ian@atticf22 ~]$ alias which
alias which='(alias; declare -f) | /usr/bin/which --tty-only --read-alias \
--read-functions --show-tilde --show-dot'
[ian@atticf22 ~]$ which which
alias which='(alias; declare -f) | /usr/bin/which --tty-only --read-alias \
--read-functions --show-tilde --show-dot'
   /usr/bin/which

上記リストでは、alias コマンドと declare  -f コマンドを括弧で囲んでグループ化し、サブシェルで実行されるようにしています。このコマンドのグループは、シェルに既知となっているエイリアスと関数を一覧表示します。グループの出力は /usr/bin/which 実行ファイルにパイプされます。/usr/bin/which 実行ファイルがターミナル上で実行されると (--tty-only オプション)、このファイルは stdin からエイリアス (--read-alias オプション) および関数 (--read-functions オプション) の定義を読み取り、それらの定義に一致するエイリアスまたは関数の出力と、現在の PATH 上で見つかった実行ファイルの基本的な出力を含めます。その他のオプションの詳細については、which の man ページを読んでください。

エイリアス、コマンド・リスト、引用符

コマンド・リストを使用するエイリアスや、シェルのその他のメタ文字を使用するエイリアスを定義する際には、慎重に行う必要があります。また、エイリアスの中でシェル変数を使用する場合には、注意して引用符を使用する必要があります。

リスト 15 では、which のエイリアスにコマンド・リストと単一引用符が使用されています。ここで、カレント・ディレクトリーの中身を、カレント・ディレクトリーとそのすべてのサブディレクトリーで使用している合計スペースとともに一覧表示するための lsdu というコマンドが必要だとします。リスト 16 に、このエイリアスを作成する正しい方法と誤った方法を示します。

リスト 16. エイリアスにコマンド・リストと引用符を使用する正しい方法と誤った方法
[ian@atticf22 developerworks]$ # Wrong way
[ian@atticf22 developerworks]$ alias lsdu=ls;du -sh
8.2M    .
[ian@atticf22 developerworks]$ lsdu
new-article.py        new-article.vbs  schema     tools        web
new-article-rich.vbs  readme           templates  validate.py  xsl
[ian@atticf22 developerworks]$ # Right way
[ian@atticf22 developerworks]$ alias lsdu='ls;du -sh'
[ian@atticf22 developerworks]$ lsdu
new-article.py        new-article.vbs  schema     tools        web
new-article-rich.vbs  readme           templates  validate.py  xsl
8.2M    .

誤った方法の例では、alias コマンドに ; メタ文字までのテキストしか含まれないことになるため、行の残りの部分が直接実行されてしまいます。このような場合には、エイリアスを構成するテキスト全体を引用符で囲む必要がありますが、単一引用符と二重引用符のどちらを使用すればよいのでしょう?

エイリアスが定義される時点でシェル変数の参照のすべてをシェルに評価させるには、二重引用符を使用します。エイリアスの実行時に参照を評価させるには、単一引用符を使用します。リスト 17 に、PWD 変数 (カレント・ディレクトリーの出力が含まれる変数) を使用して、この違いを示します。

リスト 17. エイリアスに単一引用符と二重引用符を使用する
[ian@atticf22 ~]$ alias mypwd1='echo Current directory is $PWD'
[ian@atticf22 ~]$ alias mypwd2="echo Current directory is $PWD"
[ian@atticf22 ~]$ # cd to a different directory
[ian@atticf22 ~]$ cd developerworks
[ian@atticf22 developerworks]$ mypwd1
Current directory is /home/ian/developerworks
[ian@atticf22 developerworks]$ mypwd2
Current directory is /home/ian
[ian@atticf22 developerworks]$ alias mypwd1 mypwd2
alias mypwd1='echo Current directory is $PWD'
alias mypwd2='echo Current directory is /home/ian'

Shell functions

エイリアスは役に立ちますが、パラメーターを扱う場合にはどうなるのでしょう?エイリアスで展開されるのは最初の単語だけで、コマンドラインのその他すべてのものは、展開された最初の単語に追加されます。複数のパラメーターを使用したコマンドを実行した後、その出力を何らかの方法で処理しなければならないとしたら、エイリアスでは上手く行きません。そのような場合には、シェル関数が必要となります。

シェル関数にはエイリアスに勝る以下の利点があります。

  • パラメーターを扱うことができます。
  • プログラミングの構成体 (テストやループなど) を使用して処理を強化することができます。

このチュートリアルでは単純な関数だけを取り上げます。シェル関数およびスクリプトで使用できる高度なプログラミング構成体については、この連載の次のチュートリアルで説明します。今回は、必要なコマンドを作成する方法、続いてそれらのコマンドを 1 つの関数にまとめる方法を紹介します。

例えば、ls と同じように機能する一方、ディレクトリーだけを一覧表示する ldirs というコマンドが必要だとします。おそらく最初に考える方法は、詳細なリストから始めて、フィルター処理によって d で始まる行に絞り込み、さらに処理して余分な情報を取り除くという方法でしょう。リスト 18 に、この方法の最初の段階を示します。

リスト 18. ディレクトリーをフィルター処理で絞り込む最初の試行
[ian@atticf22 ~]$ ls -l developerworks/ | grep "^d"
drwxrwxr-x. 2 ian ian  4096 Nov 13 13:06 my first article
drwxrwxr-x. 2 ian ian  4096 Sep 12  2014 readme
drwxrwxr-x. 4 ian ian  4096 Sep 12  2014 schema
drwxrwxr-x. 3 ian ian  4096 Sep 12  2014 templates
drwxrwxr-x. 3 ian ian  4096 Sep 12  2014 tools
drwxrwxr-x. 3 ian ian  4096 Mar  5  2013 web
drwxrwxr-x. 4 ian ian  4096 Sep 12  2014 xsl

明らかに、出力から最後の単語を切り取るだけでは上手く行きません。それは、名前にスペースが含まれているディレクトリーがあるからです。詳細なリストを使用するよりも、末尾に / 文字が含まれるディレクトリー名に分類したリストを作成することから始めたほうが賢明です。リスト 19 に、この方法の例を示します。

リスト 19. ls 出力を分類してディレクトリーを見つける
[ian@atticf22 ~]$ ls -F developerworks/ | grep "/$"
my first article/
readme/
schema/
templates/
tools/
web/
xsl/

遥かに好ましい結果になりました。後は、末尾の / を切り取るだけです。それには、sed を使用することで簡単に対処することができます (リスト 20 を参照)。

リスト 20. ldirs コマンド・リストの例
[ian@atticf22 ~]$ ls -F developerworks/ | grep "/$" | sed -e 's/\/$//'
my first article
readme
schema
templates
tools
web
xsl

ldirs 関数に必要となる複雑なコマンドを用意できたので、今度はそれを関数にする方法を説明します。関数は、名前とその後に続く () および複合コマンドからなります。このチュートリアルで使用する複合コマンドは、任意のコマンドまたはコマンド・リストの末尾にセミコロンを付けて、それを波括弧で囲んだものです (複合コマンドは、ホワイト・スペースを使用して、他のトークンから分ける必要があります)。より複雑な複合コマンドについては、この連載の次のチュートリアルで取り上げます。

bash シェルでは、単語 function の後に関数名を続けることができますが、この方法は POSIX 仕様の一部ではなく、dash などの必要最小限のシェルではサポートされていません。普段使用しているのとは異なる特定のシェルでスクリプトが解釈されるようにする方法については、これとは別のチュートリアルで取り上げます。

リスト 18リスト 19、およびリスト 20 のコマンドは、私のシステムにある developerworks というディレクトリーの中身を一覧表示しますが、毎回—同じディレクトリーの中身を一覧表示したいわけではありません。ところがエイリアスを使用していると、ディレクトリー名のパラメーターを置き換えることはできません。そこで、関数を使用することにします。

関数を作成する前に、パラメーターの使用方法を知っておく必要があります。パラメーターを参照するには、関数内で、表 3 に記載する bash の特殊変数を使用します。これらの変数を参照するには、他のシェル変数と同様に、変数の先頭に $ 記号を付けます。

表 3. シェル関数のパラメーター
パラメーター目的
0, 1, 2, ...パラメーター 0 から始まる位置パラメーター。パラメーター 0 は、bash を起動したプログラムの名前または (関数がシェル・スクリプト内で実行されている場合) シェル・スクリプトの名前を参照します。bash が -c パラメーターを指定して起動された場合など、その他の可能性については、bash の man ページを参照してください。単一引用符または二重引用符で囲まれた文字列は、単一のパラメーターとして渡されて、引用符は切り取られます。二重引用符で囲まれている場合は、すべてのシェル変数 ($HOME など) が展開されてから関数が呼び出されます。関数に渡すパラメーターに、半角スペースが埋め込まれていたり、シェルにとって特別な意味を持つかもしれないその他の文字が含まれていたりする場合には、単一引用符または二重引用符を使用する必要があります。
*パラメーター 1 から始まる位置パラメーター。二重引用符の内部で展開が行われる場合、展開結果は、特殊変数 IFS (フィールド分離) の先頭文字で複数のパラメーターが区切られた (IFS がヌルの場合は間に区切り文字が入りません) 1 つの語になります。デフォルトの IFS 値は、半角スペース、タブ、改行です。IFS が設定されていない場合に使用される分離文字は、デフォルト IFS と同様に半角スペースです。
@パラメーター 1 から始まる位置パラメーター。二重引用符の内部で展開が行われる場合、各パラメーターが 1 つの語になるため、"$@""$1", "$2", … と同等です。パラメーターに半角スペースが埋め込まれている可能性がある場合は、この形を使用します。
#パラメーター 0 を除くパラメーターの数。

パラメーターの数が 9 個を超える場合、$10 を使用して 10 番目のパラメーターを参照することはできません。最初のパラメーター ($1) を処理または保存してから、shift コマンドを使用して、パラメーター 1 を破棄し、$10$9 になるといった具合に、残りの全パラメーターを 1 だけ若番のパラメーターへと移動する必要があります。$# の値は、残りのパラメーターの数を反映するように更新されます。

まずは単純な関数として、その関数のパラメーターの数と、それらのパラメーターを表示するだけの関数を定義してみましょう。

リスト 21. パラメーターを表示する単純な関数
[ian@atticf22 ~]$ testfunc () { echo "$# parameters"; echo "$@"; }
[ian@atticf22 ~]$ testfunc
0 parameters

[ian@atticf22 ~]$ testfunc a b c
3 parameters
a b c
[ian@atticf22 ~]$ testfunc a "b c"
2 parameters
a b c

この例では、$*"$*"$@"$@" のどれを使用しても、出力—に大きな違いは表れません。パラメーターの数と変数参照の処理方法が変わるだけです。しかし、複雑になってくると、この違いは間違いなく重要になります。

ここで、リスト 20 のコマンド・リストを使用して ldirs 関数を作成します (リスト 22 を参照)。

リスト 22. ldirs 関数
[ian@atticf22 ~]$ # You can enter the function on one line
[ian@atticf22 ~]$ ldirs () { ls -F "$@" |  grep "/$" | sed -e 's/\/$//'; }
[ian@atticf22 ~]$ # Or you can enter it on multiple lines
[ian@atticf22 ~]$ # in which case you do not need the final semi-colon
[ian@atticf22 ~]$ ldirs ()
> {
> ls -F "$@" |  grep "/$" |
> sed -e 's/\/$//'
> }

リスト 23 に、私のシステムで developerWorks XML オーサリング・パッケージ・ディレクトリーの中身を一覧表示するために実行した ldirs 関数の出力を示します。

リスト 23. ldirs 関数の出力
[ian@atticf22 ~]$ ldirs developerworks/ ~/developerworks/xsl/7.0/
my first article
readme
schema
templates
tools
web
xsl
en_US
en_VN
es_AR
ja_JP
ko_KR
pt_BR
ru_RU
zh_CN
[ian@atticf22 ~]$ ldirs -ilrt developerworks
2511035 drwxrwxr-x. 3 ian ian  4096 Mar  5  2013 web
3019425 drwxrwxr-x. 4 ian ian  4096 Sep 12  2014 xsl
2511022 drwxrwxr-x. 3 ian ian  4096 Sep 12  2014 templates
2511036 drwxrwxr-x. 4 ian ian  4096 Sep 12  2014 schema
3023428 drwxrwxr-x. 3 ian ian  4096 Sep 12  2014 tools
3282516 drwxrwxr-x. 2 ian ian  4096 Sep 12  2014 readme
3277408 drwxrwxr-x. 2 ian ian  4096 Nov 13 13:06 my first article
[ian@atticf22 ~]$ ldirs  developerworks/my\ first\ article/
[ian@atticf22 ~]$ mkdir developerworks/my\ first\ article/"dir example"
[ian@atticf22 ~]$ ldirs  developerworks/my\ first\ article/
dir example

この ldirs の例はかなり単純なものですが、小さなビルディング・ブロックを組み合わせて、より複雑なコマンドやカスタム・コマンドを作成する手法を示しています。パイプラインとリストは、Linux (または UNIX) ツール・ボックスになくてはならないツールです。

スケルトン・ディレクトリー

~/.bash_profile、~/.bashrc、または ~/.bash_logout のようなファイルがどのようにホーム・ディレクトリーに作成されたのか、皆さんは不思議に思っているかもしれません。これらのファイルは、/etc/skel からコピーされるスケルトン・ファイルです。リスト 24 に、私のシステム上の /etc/skel に格納されているファイルを示します。ls-a オプションを指定する必要があることに注意してください。このオプションを指定しない場合には、おそらくディレクトリーの中身が表示されないはずです。

リスト 24. /etc/skeleton の中身
[ian@atticf22 ~]$ ls -a /etc/skel/
.  ..  .bash_logout  .bash_profile  .bashrc  .emacs  .kshrc  .mozilla

ホーム・ディレクトリーを作成するために、-m オプションを指定して useradd コマンドを実行すると、新しく作成されるホーム・ディレクトリーに、/etc/skel 内のファイルがコピーされます。Firefox や Korn シェルなどのプログラムでは、ここに示すように、他のディレクトリーも /etc/skel に追加される場合があります。新しいユーザー用に作成されるディレクトリーをカスタマイズするには、新しいディレクトリーおよび適切なファイルを /etc/skel に追加します。

/etc/skel の場所は、etc/defaults/useradd ファイルで構成することができます。リスト 25 に、私のシステム上にある etc/defaults/useradd ファイルの内容を記載します。

リスト 25. /etc/defaults/useradd
[ian@atticf22 ~]$ cat /etc/default/useradd 
# useradd defaults file
GROUP=100
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/bash
SKEL=/etc/skel
CREATE_MAIL_SPOOL=yes

コマンド検索パス

ご存知のとおり、bash は実行ファイルを検索する際に、PATH 変数にリストアップされているディレクトリーを使用します。PATH 変数には、エントリーがコロンで区切られた、ディレクトリーのリストが格納されます。root ユーザーの PATH は、通常は一般ユーザーの PATH とは異なります (リスト 26 を参照)。

リスト 26. 一般ユーザーの PATH と root ユーザーの PATH
[ian@atticf22 ~]$ echo $PATH
/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/home/ian/.local/bin:/home/ian/bin
[ian@atticf22 ~]$ su -
Password: 
[root@atticf22 ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

例えば、企業に /opt/company-bin というプログラム・ライブラリーがあり、このライブラリーをすべての非 root ユーザーのパスに設定したいとします。このライブラリーが PATH 変数にまだ存在しない場合に限り、これを PATH 変数の先頭に追加するという前提です。さらに、ユーザーが自分の PATH 変数に他のディレクトリーを簡単に追加するために使用できる、add2path という関数またはエイリアスを作成したいとします。これまでに学んだ知識があれば、この 2 つの作業を両方とも片付けることができます。

まず始めに、エイリアスまたは関数のどちらがより適切な選択肢であるかを決める必要があります。ここでは、当該エントリーが存在しない場合にのみ、そのエントリーを PATH に追加したいことから、パラメーターを扱う必要があることがわかります。エイリアスはパラメーターを扱わないので、ここで必要となるのは関数です。

ディレクトリーがパス上に存在するかどうかを調べる簡単な方法は、ディレクトリー名と PATH 変数をどちらも、先頭と末尾にコロン (:) を付けて囲んで、この区切り文字で囲われたディレクトリー名が、区切り文字で囲われた PATH 変数に含まれているかどうかをテストすることです。このように区切らなければ、/bin をテストすることになり、実際に検出されるのは、文字列 /bin が含まれる /usr/bin になってしまいます。シェルの波括弧展開を使用してパラメーターから文字列を削除してから、結果を元のものと比較します。リスト 27 に、使用できる基本的な構成体の例を記載します。

リスト 27. ある文字列が別の文字列に含まれているかどうかをテストする
[ian@atticf22 ~]$ # Augment the path
[ian@atticf22 ~]$ augpath=":$PATH:"
[ian@atticf22 ~]$ # demonstrate with /usr/bin
[ian@atticf22 ~]$ augdir=":/usr/bin:"
[ian@atticf22 ~]$ echo -e "$augdir\n$augpath\n${augpath/$augdir}":/usr/bin:
:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:/home/ian/.local/bin:/home/ian/bin:
:/usr/local/bin:/usr/local/sbin/usr/sbin:/bin:/sbin:/home/ian/.local/bin:/home/ian/bin:
[ian@atticf22 ~]$ test "$augpath" != "${augpath/$augdir}" && echo Found || echo Not
Found

この時点では add2path 関数を簡単に作成することができます。仲介役の変数を local として宣言すると、その変数は関数の外部では既知になりません。リスト 28 に、add2path 関数とその使用方法の例を記載します。

リスト 28. add2path 関数とその使用方法
[ian@atticf22 ~]$ add2path ()
> {
> local augpath augdir
> augpath=":$PATH:"
> augdir=":$1:"
> test "$augpath" = "${augpath/$augdir}" && PATH="$1:$PATH"
> }
[ian@atticf22 ~]$ add2path /opt/company-bin
[ian@atticf22 ~]$ echo $PATH
/opt/company-bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:
    /sbin:/home/ian/.local/bin:/home/ian/bin

このチュートリアルの最初のほうでプロファイルについて説明したので、おわかりだと思いますが、このコマンド・シーケンスをシステム全体の関数として追加するには、/etc/profile.d 内に company-bin.sh ファイルを作成するのが最善の方法となります。このファイルを作成するには、root 権限が必要です。非 root ユーザーの PATH に /opt/company-bin を追加する必要があることを思い出してください。リスト 29 に、このファイルの内容を記載します。

リスト 29. /etc/profile.d/company-bin.sh ファイル
[ian@atticf22 ~]$ cat /etc/profile.d/company-dir.sh 
# Declare the add2path function

add2path () 
{ 
    local augpath augdir
    augpath=":$PATH:"
    augdir=":$1:"
    test "$augpath" = "${augpath/$augdir}" && PATH="$1:$PATH"
}

# Add /opt/company-bin if not already on non-root PATH
[ $(id -u) -ne 0 ] && add2path /opt/company-bin

この例をご使用のシステムで試してください。

これで、bash シェル環境を使用およびカスタマイズする方法についての説明は終わりです。


ダウンロード可能なリソース


関連トピック


コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Linux
ArticleID=1029632
ArticleTitle=Linux の 101 試験対策: シェル環境のカスタマイズと使用
publish-date=04142016