Linuxのシェル環境をカスタマイズしてみる- LPIC対策(シェルとスクリプト)

Linuxのシェルについてあまり詳しくなかったのでまとめてみました。
(実際はLPIC対策用)

#### 環境変数とシェル変数

シェルはユーザ毎に違った環境を用意することが出来、ユーザ環境は様々な変数によって定義されている。
変数には、`環境変数`と`シェル変数`の2種類がある。

* 環境変数
<pre>
シェル自身と、そのシェルから起動される全てのプロセス(コマンドや別のシェル)で有効となる変数。
有名なのは、コマンドのパスが書いてある`PATH`や、ホームディレクトリのフルパスを表す`HOME`などがある。
</pre>

* シェル変数
<pre>
そのシェル内でのみ有効(他のシェルやプログラムでは有効にならない)
シェル変数は`export`コマンドでエクスポートすると`環境変数`になる！
</pre>

設定されてる環境変数の確認方法


```
env
printenv
```

また、`set`コマンドでシェル変数と環境変数を表示することも出来る。

#### setコマンド

シェルには色んなオプションがあり、setコマンドを使ってオプションのON/OFFを切り替えることが出来る。

書式

```
set [+o] [-o] オプション名
```

* オプションの一覧

|オプション|説明|
|:----|----:|
|allexport|作成変更した変数を自動的にエクスポートする(環境変数にする)|
|emacs|emacs風のキーバインドにする|
|ignoreeof|`Ctrl+D`でログアウトしない|
|noglob|メタキャラを使ったファイル展開しない|
|nocolorber|出力リダイレクトを禁止|

`noglob`を使った例を見てみましょう

```bash
#メタキャラでファイル展開出来てる
$ls *.txt
hoge1.txt  hoge2.txt

# メタキャラでのファイル展開をOFFにする
$set -o noglob
$ls *.txt
ls: cannot access *.txt: そのようなファイルやディレクトリはありません

$set +o noglob
$ls *.txt
hoge1.txt  hoge2.txt
```

使い道がよくわかりませんね。笑

因みに`set -o`でオプションの設定状況が確認出来ます。
<pre>
$set -o
allexport      	off
braceexpand    	on
emacs          	on
errexit        	off
errtrace       	off
functrace      	off
hashall        	on
histexpand     	on
history        	on
ignoreeof      	off
interactive-comments	on
keyword        	off
monitor        	on
noclobber      	off
noexec         	off
noglob         	off
nolog          	off
notify         	off
nounset        	off
onecmd         	off
physical       	off
pipefail       	off
posix          	off
privileged     	off
verbose        	off
vi             	off
xtrace         	off
</pre>

#### エイリアス

これはよく使います。
エイリアスというのは別名の事で、コマンドに別名を付けたり、コマンドとオプションをひとまとめにして新しいコマンドかのように使えるようになります。
実際に見てみましょう。


```bash
$ls
hoge1.txt  hoge2.txt

# lsにエイリアスを設定する
$alias ls='ls -l'
$ls
合計 0
-rw-rw-r-- 1 *** webadmin 0 12月  9 21:07 2014 hoge1.txt
-rw-rw-r-- 1 *** webadmin 0 12月  9 21:07 2014 hoge2.txt
```

##### エイリアスの無視と、解除

```bash
# aliasを設定
$alias ls='ls -l'
$ls
合計 4
-rw-rw-r-- 1 *** webadmin 13 12月  9 21:13 2014 hoge1.txt
-rw-rw-r-- 1 *** webadmin  0 12月  9 21:07 2014 hoge2.txt

# 先頭にバックスラッシュをつけるとaliasを無視する
$\ls
hoge1.txt  hoge2.txt

# aliasの解除
$unalias ls
$ls
hoge1.txt  hoge2.txt
```

#### 関数の定義

bashの組み込みコマンドの`function`コマンドを使うと、bashシェル上で利用出来る独自の関数を定義出来るようになります。

書式

```
function 関数名() { コマンド; }
```

例として、シンボリックリンクのみを表示する`lslink`関数を作ってみる

```bash
# シンボリックリンクは必ず->という文字が入ってる
# ただ、普通にgrepで>とか使うとオプションと勘違いされるから、--をつけてオプションじゃないことをアピール
$function lslink() { ls -l | grep -- '->'; }

# シンボリックリンクだけ表示された！
$lslink
lrwxrwxrwx 1 *** webadmin    9 12月  9 21:18 2014 hoge1_sib.txt -> hoge1.txt
```

関数に引数を渡す事も可能です。
引数に渡したディレクトリ内でのシンボリックリンクを探す関数を作ってみます。

```bash
function lslink() { ls -l $1 | grep -- '->'; }

# 引数はスペースで渡します
$lslink fuga
lrwxrwxrwx 1 *** webadmin 10 12月  9 21:18 2014 fuga -> hoge/fuga/
```

この時に、`set`コマンドを使って、シェル変数を確認してみるとわかりますが、
今作った関数がシェル変数として登録されてます。
つまり、bashで変数名と関数名を区別しません。
なので重複しないように注意して下さい。

`declare -f`コマンドで、定義されている`関数のみ`を表示することも出来ます。

##### 関数の削除

シェル変数の削除と一緒で、`unset`コマンドを使います。

```bash
$lslink
lrwxrwxrwx 1 *** webadmin   10 12月  9 21:18 2014 fuga -> hoge/fuga/
lrwxrwxrwx 1 *** webadmin    9 12月  9 21:18 2014 hoge1_sib.txt -> hoge1.txt

# lslink関数を削除
$unset lslink

# 消えた
$lslink
-bash: lslink: コマンドが見つかりません
```

#### bashの設定ファイル

シェルを起動する度に、いちいちシェル変数にエイリアスを設定したり、便利関数を定義するのはあまりにも面倒です。
そこで、bashにはこれらの定義を自動的に行うための設定ファイルが用意されてます。
表にまとめます。

|ファイル|説明|
|:---|---:|
|/etc/profile|ログイン時に実行されて、全ユーザから参照される|
|~/.bash_profile|ログイン時に実行|
|~/.bash_login|~/.bash_profileがない場合に、ログイン時に実行|
|~/.profile|~/.bashr_profileも~/.bash_loginもない場合に、ログイン時に実行|
|~/.bashrc|bash起動時に実行|
|~/bash_logout|ログアウト時に実行|

※/etcディレクトリ以下の設定ファイルは全ユーザに影響し、~/以下は各ユーザにしか影響しない。




#### /etc/profileには何が書かれてるのか

```bash:/etc/profile
 31     USER="`id -un`"  # $USERにユーザ名を入れてる
 32     LOGNAME=$USER　　 # $LOGNAMEにユーザ名を入れてる　
 33     MAIL="/var/spool/mail/$USER"　　　# MAILの設定

 47 HOSTNAME=`/bin/hostname 2>/dev/null` 
 48 HISTSIZE=1000

# 環境変数にエクスポートしてる
 55 export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE HISTCONTROL
```

**/etc/profileの先頭に、あんま変更するなって事が英語で書いてあった。**

**因みに、/etc/profile内で、/etc/profile.d以下のファイルを全て実行している**

#### ~/.bash_prifileには何が書かれているのか

`~/.bash_profile`はログイン時に実行されるとありましたが、何が書かれているのか。

```bash:~/.bash_profile
  1 # .bash_profile
  2 
  3 # Get the aliases and functions
  4 if [ -f ~/.bashrc ]; then  # ~/.bashrcがあったら.bashrcを実行する
  5     . ~/.bashrc 
  6 fi
  7 

　# nvmってのはnode.jsのパッケージ管理システムです。
  8 if [[ -s ~/.nvm/nvm.sh ]];　　# ~/.nvm/nvm.shがあったら実行
  9   then source ~/.nvm/nvm.sh
 10 fi
 11 
 12 # User specific environment and startup programs
 13 
 14 PATH=$PATH:$HOME/bin
 15 
 16 export PATH
```