5.1.2. シェルの設定/Shell configuration

5.1.2.1. シェルはインタープリタ/The shell is an interpreter

シェルは、ユーザが入力したコマンドラインをその都度実行する、インタープリタ (interpreter, 逐次翻訳プログラム)です。 シェルはユーザからプログラムを入力してそれを実行します。 ユーザが入力するのは「シェル言語」のプログラムであるということになります。

シェル言語は、プログラミング言語であり、変数もあれば、if文やforループもあります。 シェル言語のプログラムを格納したファイルは、シェルスクリプト(shell script)と呼ばれます。

シェルの変数はシェルの設定にも使われます。 シェルは、起動や終了のタイミングで、決まった名前のシェルスクリプトを実行する ようになっていて、これらの起動スクリプトや終了スクリプトを用いて設定処理や 作業終了時の後始末の処理をすることができます。

The shell is an interpreter program, a program that reads some input, do something based on the input, then read some more. The shell is reading a sequence of commands as input, which can be seen as a program. What the user is typing is in fact a program written in the “shell language”.

The shell language is a programming language; it has variables, if statements and for loops. A file containing a program in shell language is called a shell script.

Shell variables are also used for configuration. The shell will run certain shell scripts upon startup and termination. These scripts can be used for configuration.

5.1.2.2. シェル変数/Shell variables

シェルの変数には「=」で値を代入します。シェルの変数で保持できるのは文字列です。:

Shell variables can have values assigned with “=”. Values will be stored as strings:

$ A=file.c
$ B=main.c sub.c func.c

変数名と代入の「=」の間に空白を入れてはいけません。空白が入ると、変数名のつもりで 入力した名前がコマンド名と解釈されてしまいます。:

Be careful not to put extra space before the assignment operator. If you do, the left hand side will be treated as a command name, rather than a variable name:

$ C = hello.c        # SYNTAX ERROR: extra space around "="

この例は、Cというコマンドに、2つの引数「=」と「hello.c」を渡しているものと解釈されます。

The above example will be treated as a command “C” being given 2 arguments “=” and “hello.c”.

変数の参照には「$変数名」という表現を使います。:

Variable values can be referenced by the expression “$variable_name”:

$ cp $A backup_directory

変数Aに名前が保持されているファイルがコピーされます。

The file with the name stored in variable A will be copied.

5.1.2.3. シェル変数と環境変数/Shell variables and environment variables

シェルの主な働きは、ユーザが入力したコマンドを子プロセスとして起動して実行することです。

通常のシェル変数は、その変数が定義されたシェルのプロセスの中にしか存在せず、 子ブロセスには引き継がれません。

これに対して、環境変数(environment variable)と呼ばれる種類の変数は、 シェルが起動する子プロセスに、値が引き継がれます。 環境変数は、プログラムにコマンドライン引数以外のパラメータを渡したい時などに使われます。

The primary function of the shell is to run commands that the user entered in newly created child processes.

Normal shell variables are stored only in the shell process where the variables were assigned, and will not be passed on to child processes.

In contrast, environment variables will be passed on to child processes. Environment variables is used to pass parameters to programs in addition to the command line arguments.

変数の値を確認するには、echo を使います:

Variable values can be checked with echo:

$ echo $HOME
$ echo $PATH

シェル変数に対して、export操作をすると、そのシェル変数は環境変数になります:

By exporting a variable, the variable becomes an environment variable:

$ export A

代入とexportを同時に行うこともできます。:

Assignement and the export operation can be done at once:

$ export B=value

5.1.2.4. 環境変数PATH/environment variable PATH

環境変数の利用例を紹介します。最もよく使われる環境変数の一つが PATH です。

シェルにコマンドを入力したときに、シェルは入力されたコマンドをファイルとして探します。 その時に探索するディレクトリの一覧を指定するのがPATHです。

When a command is entered to the shell, the shell will search for the command as a program file. PATH defines the list of directories to search.

PATHには、複数のディレクトリを「:」で区切って列挙します。:

The form of PATH is a colon(‘:’) separated list of directory names:

$ PATH=/usr/bin:/bin:/usr/local/bin

PATHはすでに環境変数になっているので export する必要はありません。

PATH is already made as an environment variable, so you do not need to export.

探索は、先頭のディレクトリから順に行われます。

Searching is done in left-to-right order.

シェルがコマンドを探索するのは、PATHに指定されたディレクトリだけであり、カレント ディレクトリは含まれないことは、知っておいたほうがよいでしょう。

Note that the shell only searches the directories listed in PATH, and it DOES NOT search the current working directory.

自作のプログラムをコンパイルして実行しようとするような場合は、PATHにそのディレクトリ が含まれていないことが多いと思います。 PATHに登場しないディレクトリに置いてあるプログラムを実行するには、 そのプログラムのファイル名ではなく、”/”を一つ以上含んだパス名を指定する必要があります。 カレントディレクトリにあるファイルの場合には、”./”、つまり 「カレントディレクトリの下にある」というパスをつけて、”/”を含んだパス名に仕立てます。

これは安全とセキュリティのための措置です。普段はPATH経由で実行しているプログラムと 同名のプログラムがカレントディレクトリにあったとします。 この場合に、ファイル名だけでカレントディレクトリのプログラムを実行できてしまうと、 意図に反してカレントディレクトリにおいてあるプログラムを実行してしまうリスクがあります。 PATHにないプログラムを実行したいときには、ユーザがどのプログラムの実行を 意図しているのかをはっきり示すために、”/”を含んだパス名を入力することになっています。

When running a program that you are developing, the developed program file is often stored in a directory that is not part of PATH. To run a program in a directory outside of PATH, you need to specify a path name, with at least one “/”, not just the file name. If the fiel you want to run is in the current directory, you need to add a “./” in front of the filename, so that it becomes a path name that has a slash.

This is a measure taken for safety and security concerns. Imagine that there happened to be a program file whose name was the same as a program you regularly use through PATH. If you could execute that program just by specifying the file name, there is a risk that you might have intended to run the standard program through PATH, but the shell picked up the local file in the current directory. To avoid such risk that results from ambiguity, to run a program outside of PATH, you always need to give a path name.

Note

「./」という指定に意義があるのは、プログラムをシェルから実行する場合のみです。 その他の場面、例えばエディタに編集対象ファイルを指定する時などには、ファイル名に 「./」をつけても、特に作用はありません。

The form “./” only has meaning in the context of “running a program from the shell”. In other contexts, such as specifying the text editor which file to edit, there is no effect in adding “./” before the file name.

5.1.2.5. 環境変数HOME/environment variable HOME

環境変数HOMEには、自分のホームディレクトリのパス名が設定されます。 自分で値を設定することはありませんが、シェルスクリプトなどの中で参照すること がよくあります:

The environment variable HOME will be set to your home directory. You never need to assign a value to HOME, but many shell scripts read the value:

# inside a shell script..
USER_SSH_PRIVATE_KEY=$HOME/.ssh/id_rsa

HOMEには絶対パス名が入っているので、上記の例のように書くと、ホームディレクトリ の下の秘密鍵のパス名が絶対パス形式で得られます。

Since HOME holds the home directory path in absolute path form, in the above example the expression will result in an absolute path name to the ssh private key file.

シェルの動作の中でHOMEが参照される場合もあります。 例えば、ディレクトリ名を指定せずに:

HOME will also be used by the shell to provide its functions. When you use cd without a directory argument:

$ cd

とだけ入力すると、ホームディレクトリに移動しますが、これも、環境変数HOMEを参照して 実現されています。

cd will use the value of $HOME as the default target directory.

5.1.2.6. シェルのカスタマイズ項目/Shell customization items

5.1.2.6.1. コマンドのエイリアス/Command aliases

タイプするのが長いコマンドに、別名(エイリアス)を与えることができます。 例えば、lsコマンドに、毎回同じオプションを指定したいような場合には、 次のようにエイリアスを定義することができます:

alias ls="ls -Fs --color=auto"

このようにしておくとlsは、ここでの定義内容の “ls -Fs –color=auto” に展開されます。

5.1.2.6.2. プロンプト文字列の設定/Setting prompt strings

シェルのプロンプト(prompt, ユーザに入力を促す)文字列はシェル変数でカスタマイズできる。 例えば、bashにおいては、PS1という変数がプロンプトを指定する変数であり、その値の 中に、キーワードを書くと、ユーザ名やホスト名、カレントディレクトリの値などに展開される。:

$ PS1="\u@\h:\w{\!}\$ "
hideo-t@server1:~/work{10}$

において、\uはユーザ名、\hはホスト名、\wはワーキングディレクトリ、\!はヒストリ番号 \$は一般ユーザであれば「$」、rootであれば「#」に展開される。(UNIXでは、権限の強い rootユーザーで作業をしている時には、慎重に操作するように注意を促すために、シェルの プロンプトの末尾を「#」に切り替える慣習がある。)

他にもいろいろな指定が可能なので、興味のある人はシェルのマニュアルを調べてみるとよい。

5.1.2.7. シェルの初期化スクリプト/Shell startup scripts

シェルは、起動時に特定の名前の初期化スクリプトファイルを読み込みます。 そのファイルの中に環境変数への代入などを記述します。 ファイルを更新した後で、ファイルがシェルに読まれた時点で設定が有効になります。 ファイルを書き換えただけでは、使用中のシェルには変更は反映されないので注意してください。

Shell programs will read an initialization script file with a specific name upon startup. Environment variables can be set in that file. Settings written to that file will take effect only when the shell reads the file. Note that simply writing to the file will not have any effect to the shell you are using.

初期化スクリプトの名前は、シェルの種類によって多少異なっています。 ここではbashに関して説明します。

The name of the script files somewhat differs from shell to shell. Here we will show initialization files for bash.

See also

bashの公式ドキュメントにおける、起動スクリプトの説明は:

For the official documents for bash initialization scripts, see:

5.1.2.7.1. シェルの初期化にまつわる歴史/The history behind shell initialization

シェルの初期化に関しては、一見不可解なルールが存在します。 シェルの初期化の仕組みを理解するには、このルールを理解する必要があります。

これらのルールは数十年前のハードウェア事情やソフトウェア事情を考慮して、設計されました。 現在の仕様を合理的に説明するために必要最低限の経緯をここでは紹介します。 これは、「なんで仕様がこうなっているのか?」ということを気にする場合にだけ 理解する必要があります。単に仕様を把握して使う分には経緯を覚えておく必要は ありません。

There are some confusing rules regarding shell initialization. Understanding these rules is necessary to understand how shell initialization works. The history is required only when you want to understand why the current specification is in a certain way. If you just need to know what the specification says and use it, you don’t need to memorize the following history.

These rules were designed several decades ago, based on the hardware and software situation of those days. In this page the minimum amount of history required to explain the current design of the shell is explained.

概要は次のようになります。:

  • シェルはユーザから対話的に使われる場合と、スクリプトの実行のために非対話的に実行される場合がある。

  • 対話的に使うシェルでは、利便性を高めるためにたくさんの項目を初期化したいというユーザが多い。 1980年台ころの計算機では、この初期化自体に無視できない時間がかかることがあった。

  • 非対話的に使うシェルでは、利便性のための設定の殆どは不要であり、早く設定が完了 することが重視された。

  • シェル自体に、対話的に使われているのか非対話的に使われているのか判別できる機能 が作られ、それにあわせて読み込む初期化ファイルが切り替えられるようになった。 非対話的なシェルでは時間のかかる初期化を省略するようになった。

  • 対話的なシェルにはさらに、ログインシェルか一般のシェルかという区別があり、 ログインシェルでだけ読み込まれる初期化ファイルが設けられた。

  • 1990年代初頭のUNIXシステムでは、一旦テキスト画面でログインした後でグラフィック デスクトップを起動するような使い方をしていた。 その場合、一旦ログインシェルが起動され、ユーザはログインシェルに対してコマンド を入力することでグラフィクスを起動していた。

  • その後ソフトウェアが整備され、最初からグラフィカルな画面に対してログインする ようになり、ログインシェルを経由することなしに操作が可能になった。その場合、 ログインシェルでしか読み込まれない設定ファイルが読み込まれなくなり、 以前から利用し続けていた初期化ファイルが効かなくなってしまうという問題があった。

  • グラフィカルデスクトップ時代のログインシェル問題に対する、UNIXやLinuxでの 対処は、ユーザのログイン成功と共に開始する「セッションマネージャ」プログラム が従来のログインシェルに変わって、ログインシェル用の初期化ファイルを読み込む というものであった。

  • これに対して、シェルを始めとする多くの要素をUNIXから流用しているものの、 UNIXそのものではない macos においては、グラフィカルにログインしただけでは ログインシェル用の初期化ファイルはどのプロセスも読み込まない。そのかわりに ターミナルプログラムを起動する度に、ログインシェル用の初期化ファイルを 読み込むようにした。

  • macosとlinuxの双方を使う人の場合、どちらにも通用する設定の仕方をするのがよい。

Here is the outline:

  • Shells can be used interactively from a user, or non-interactively for running script files.

  • For interactive shells, many users wished to do a lot of configuration for increased convenience. For computers in the 1980’s, this required non-negligible processing time.

  • For non-interactive shells, configuration for convenience was unnecessary, and short startup time was more important.

  • The shell program became capable of telling whether it is being used interactively or not. Based on that information, different initialization scripts could be loaded. This was used to eliminate the time consuming setup from non-interactive shells.

  • Interactive shells are further divided into login shells and non-login interactive shells. There is an initialization script file that is read only by login shells.

  • In UNIX systems of the early 1990s, users would login to a computer on a text-only screen, and after that the user would type a command to start the graphical desktop system. In such case, that first shell was the login shell, and the user would use the login shell to start the desktop system.

  • Later on, as more software was developed, users logged in to the system from a graphical screen without dealing with a login shell. For users at that time, this was a serious problem because the start up file for login shells would no longer have an effect.

  • The solution to this problem by UNIX and Linux systems is to let the “session manager” program, read the shell initialization file in place of the login shell. The session manager is a program that is started upon user login.

  • The solution to the same problem by macos was different. macos is not exactly a UNIX based system, but it borrows many components from UNIX. In macos the shell initialization file for login shells is not read by a session manager. Instead, the file is read each time a new terminal window is opened.

  • Users who use both macos and linux should use the files that is applicable to both operating systems.

5.1.2.7.2. $HOME/.profile

.profileは、古くからあるシェルである bourne シェル(発音は「ボーン」) の ログインシェル の初期化ファイルです。 ログイン直後に起動されるシェルがログインシェルで、ログインした後で追加で起動する シェルとは区別されます。 bashもこのファイルを認識し、同じようにログイン時に読み込みます。

このファイルを読みこんだ場合には、他の初期化ファイルは自動的には読み込ません。

The .profile file has its origin in the bourne shell, which is an old time shell, and the file is the initialization script for login shells. The first shell that is invoked upon login is called the login shell, and is distinguished from other shells that are invoked after the user logged in. Bash also recognizes this file, and reads it by the login shell.

When this file is read, no other startup file is read automatically.

5.1.2.7.3. $HOME/.bash_profile

bashのログインシェル用初期化スクリプトであり、これが存在する場合には、 .profileはあったとしても無視されて、こちらが読み込まれます。 もし何らかの経緯で.bash_profileが作成してある場合には、 .profileの方に設定を書いてもbashは読み込まないので要注意です。

The .bash_profile is the bash startup script for login shells. When this file is present, $HOME/.profile will be ignored. If for some reason this file exists, editing .profile has no effect.

5.1.2.7.4. $HOME/.bashrc

同じくbashの初期化ファイルです。 このファイルはログインシェル以外の、対話的に起動されるシェルでは読み込まれます。 対話的ではないシェル、というのは、 例えばシェルスクリプトを実行するために起動されたシェルが該当します。 それらにおいては .bashrc は読み込まれません。

This is a startup script for bash. It will be read for interactive, non-login shells. An interactive shell is contrasted to a non-interactive shell, which is used to run shell scripts. A non-interactive shell will not read .bashrc.

5.1.2.7.5. どの設定ファイルに書いたらよいのか/Which file should be used?

上記の仕組みを踏まえて、定義する内容に応じて、それぞれ以下の ファイルに書くとよいことになります。

  • ログインシェルかどうかに関わらず設定したい項目は .bashrc に書く。

  • .profile または .bash_profileからは、 .bashrc ファイルを読み込み、さらに、 ログインシェル特有の処理を書きたければ、そこに書く。 .profile がすでに存在すればそこに追記する。 .profile が無ければ、.bash_profileに書く。 スクリプトの読み込みには、ピリオドコマンド “. ファイル名” を使います。

Taking the above behavior in account, you can use the files as follows:

  • Put any customization that are common to login and non-login shells into .bashrc.

  • Put any customization specific to login shells into .profile or .bash_profile, and read .bashrc from that file. Script files can be read with the period command “. filename”.

.profileの例:

Example of .profile:

# This is .profile
# put login shell specific customization here.
# If you want to customize PATH by adding a path to the system default
# PATH, you should do it here, and not in .bashrc.
MYBIN=$HOME/.local/bin
export PATH=$PATH:$MYBIN
# read in .bashrc if the file exists.
if [ -f $HOME/.bashrc ]; then
    . $HOME/.bashrc
fi

.bashrcの例:

Example of .bashrc:

# This is .bashrc
# Do not define PATH here.
# Define aliases:
alias ls='ls -Fs'
# Define the prompt:
PS1="\u@\h:\w{\!}\$ "

5.1.2.8. スクリプトを読み込むコマンド/A command to read scripts

初期化スクリプトはシェルの起動時に自動的に読み込まれます。 これ以外のタイミングで、初期化スクリプトを読み込ませるには、sourceコマンド またはピリオドコマンド “.” を使います。両者の機能は同じです:

Startup scripts are read by the shell automatically on startup time. If you want to make the shell read a startup script on any other timing, use the “source” command or the “.” (period) command. Both commands have the same function:

Either
$ source ~/.bashrc
or
$ . ~/.bashrc

のどちらかを実行すると、現在実行中のシェルが .bashrc ファイルの内容を読み込みます。

Either will cause the current shell to read the contents of .bashrc.

sourceコマンドやピリオドコマンドを初期化スクリプトの中で使うと、 ちょうどC++言語の #include 指令のように、 一つのファイルの中に別のファイルを取り込む働きをします。

If you use the source command inside a script, it will include the specified script, just like an #include directive in C++,

5.1.2.8.1. GUIプログラムに関する注意/A note on GUI programs

bashの中で定義した環境変数は、bashから起動するプログラムには伝達されますが、 デスクトップのアイコンや、ファイル操作のGUI(MacOSのFinderやWindowsのExplorer) からプログラムを起動する場合、OSやGUIのシステムによって、環境変数が伝達されたり、 されなかったりします。Windowsでは伝達されません。Ubuntu Desktop, MacOSXでは伝達されるようです。 GUIプログラムに環境変数の値が伝わらなかった場合には、疑ってみてください。

Environment variables that were assigned in bash will be passed on to programs that are invoked from bash. However, when you invoke a GUI program outside of bash, from icons on the GUI desktop, or from a file system navigation tool such as MacOS Finder or Windows Explorer, environment variables set by bash may not be passed to those programs, depending on your operating system and window system. It will not be passed in Windows. It will be passed in Ubuntu Desktop and MacOSX. If you encounter problems with a GUI program not getting environment variables, check if this is the cause.