04. 標準入出力, リダイレクション,パイプ / コマンド先読み評価

gemini generated image



この回の授業の到達目標

  1. コマンドには「入力」「通常の出力」「エラー出力」があることを説明できる.
  2. コマンドの出力をファイルに保存できる.
    例: command > file
  3. 既存ファイルを壊さずに追記できる.
    例: command >> file
  4. ファイルをコマンドの入力として渡せる.
    例: command < file
  5. 2つ以上のコマンドをパイプでつなげる.
    例: command1 | command2
  6. tee を使って,画面表示とファイル保存を同時にできる.
  7. shell の先読み評価を理解できる.

基本編

標準入出力, リダイレクション,パイプ

  短い単純なプログラムを組み合わせて複雑な動作を実現する

unix の重要なポリシーの一つ.
短い単純なプログラムのほうが作りやすく,性能もあげやすく,かつ,バグも少なくて,良いことずくめだという考え.


上に述べたのは Unix の重要なポリシーの一つで, そのための仕組みの一つがこれから説明する標準入出力とその制御であるリダイレクション,パイプラインだ.

まず少し基本的な話をすると,unix では通常のプログラムは 「標準入力」「標準出力」「標準エラー出力」という特別な入出力先を持っていて,通常は下記のような関係性と使われ方をしている.

そしてこの「標準入出力」が繋がる相手をユーザーがプログラムを起動するとき毎に自由に制御することができ, その方法が「リダイレクション」や「パイプライン」なのである.

aa

■ 標準入出力とその制御(リダイレクション,パイプ)の様子 ■



上図のように,プログラムの入出力先を''「プログラムの実行時にユーザが勝手に変えられる」''のである. 上で述べたポリシーにより ''「unix には単機能プログラムが たくさんある」'' ため,この機能と組み合わせると

まるでプログラミングをしたかのような,かなり自由なことがプログラミング不要で簡単に実現できる という「おいしい」状況が unix に出現する. これは本当に便利なので,ぜひ習得しよう.



標準入出力とは何か

unix ではプログラムはチャネル,もしくは デスクリプタ(ファイル記述子)とよばれる出入り口ファイルを用いてデータの入出力を行なう. 機器や環境に依存しない汎用入出力を可能とする目的で,unix ではこのうちの最初の 3つ(0 〜 2番)のデスクリプタを特別なものとして決めている. これらが標準入出力とよばれるものであり,次のような性質を持っている.

IO(Input/Output) 説明
標準入力(stdin) プログラムが入力に使う.
デフォルト値は 端末キーボード
標準出力(stdout) プログラムが出力に使う.
デフォルト値は 端末ディスプレイ.
標準エラー出力(stderr) プログラムがエラー出力に使う.
デフォルト値は端末ディスプレイ.

これら標準入出力によるデータの入出力の相手はプログラムを起動したシェルが決める約束になっている.

注: 標準出力と標準エラー出力は別の流れである. そのため,command > file としても,エラーメッセージは file に入らず画面に出ることがある.

リダイレクション

redirection

  標準入出力先を「コマンド投入時に」変更できる

これを上手に使えば,同じプログラムの出力をファイルへ出力したり,ディスプレイへ出力したり, 出力させなかったりと変更することを「プログラム側で全く考慮する事なく」 行なうことができる.

この「標準入出力先を変更すること」,すなわち標準入出力の制御を,(I/O)リダイレクションとよぶ.

そこで,以下に「一つのプログラムに対する」具体的なリダイレクションの方法を示そう.

注意: 二つのプログラムの入出力を直接繋げてしまう「同時リダイレクション」は特別に「パイプライン」と呼ばれる. 詳しくは後述する.

リダイレクションのやり方

標準入力を hoge ファイルに変更するには

sh/csh/fish 共通
コマンド < hoge

標準出力を変更するには

sh/csh 系 fish の場合 意味
コマンド > hoge

注: noclobber 変数をセットしておくと,消去・上書きを防げる.
同左.

ただし noclobber 変数を無視して動作する.
標準出力を hoge ファイルに変更.

注: ''hoge'' ファイルがなければ作成する.
既に存在するならば内容は消去されて上書きされてしまう

コマンド >> hoge

注: noclobber 変数をセットしておくとエラーになり,書き込めない.
同左.

ただし,noclobber 変数を無視して動作する.
標準出力を hoge ファイル末尾に追加する.

注: ''hoge'' が存在しなければ作成される.

  注意 : 上にあるように,リダイレクション コマンド > file では,既に存在する file の中身を消して書き込みかねない. 大事なファイル名を指定すると内容が失われるかもしれないので注意すること. 練習では必ず work などの専用ディレクトリを作って,その中で作業すること.

リダイレクションの実例

例えば,ls -lga の結果をファイルに保存してゆっくり調べたいとしよう. こういうときは

1ls -lga > sample-file

とすれば, ''sample-file'' という名前のファイルに ls -lga の結果が収められる.

そして、例えば less コマンドを使って less sample-file とすると

 1合計 108
 2drwxr-x--- 17 osboxes 4096  4月 23 18:11 .
 3drwxr-xr-x  4 root    4096  2月 26 15:12 ..
 4-rw-------  1 osboxes  395  4月 17 20:49 .bash_history
 5-rw-r--r--  1 osboxes  220  2月 26 15:12 .bash_logout
 6-rw-r--r--  1 osboxes 3771  2月 26 15:12 .bashrc
 7drwx------ 11 osboxes 4096  4月 14 18:37 .cache
 8drwx------ 15 osboxes 4096  4月 17 20:49 .config
 9drwx------  3 osboxes 4096  4月 17 20:30 .emacs.d
10  …略…

というように,中身をいつでも繰り返しゆっくり見ることができる.

さらに,ここにあるファイルをサイズ順にリストアップしてみたいな〜 と思ったとしよう. すると,sort コマンド(中身を並べる)を使って, ''sample-file'' の中身の,''この場合は'' 4番目の要素を大きい順に並べればよい.

  ls -lga コマンドの結果の何番目にファイルサイズが表示されるかは環境に依存するので,自分で数えてから実行しよう.上の例では4番目に表示されている.

このケースでは,入力と出力の両方をリダイレクションすれば便利だ.

だから例えば以下のようにすればよい.

1sort -k 4 -nr < sample-file > sample-file2

この例では、sort コマンドの入力先を sample-file に,出力先を sample-file2 にリダイレクトしている. こうして、 ''sample-file2'' に望みの結果が入る.

  混乱しないように、sort < ファイル名sort ファイル名 の違いなどを示しておこう.

書き方 意味
sort < ファイル名 シェルがそのファイルを標準入力につなぎ、sort は標準入力から読む.
sort ファイル名 sort に「そのファイルを読め」と命令する.
(後で学ぶパイプの例)
cat ファイル名 | sort
catがファイルの中身を読み上げた内容が sort の標準入力につながる.

  実習

  • 上に示した実例と同じ作業をやってみる.
  • さらに,同様の方法で, 二つのディレクトリの中でサイズの大きな方から順に5つのファイルをリストアップするにはどうしたらよいか考えよ. そして実際に試してみよ.

覚えておくと便利なリダイレクト先 /dev/null
ファイルとしては空っぽの "ブラックホール" と思えば良い.

上の表を見ても分かるように,リダイレクト先には通常はファイルを指定する. この時,unix に存在する特別なファイル ''/dev/null'' が非常に便利に使えるので覚えておこう. このファイルは「ブラックホールファイル」とでも言うべき次の性質を持っている.

  • 標準入力先に指定すると,「何も出てこない」
  • 標準出力先に指定すると,「全て飲み込んで,何も変化しない」

よって,とっておく必要のない出力を捨てることができる(しかも素早く). やり方は下の通り.

sh 系, fish csh 系
コマンド &> /dev/null コマンド >& /dev/null

これで標準出力と標準エラー出力の両方がブラックホールへと消えていく.

ジョブをバックグラウンドで実行させていて,その出力が邪魔な時や, コマンドを nohup で実行させる場合, プログラムの計算速度などを純粋に測定するためにデータの出力に時間がかかると困る時,などに使えるテクニックだ.

パイプ

原理的には,リダイレクションを使えば,

Program A (出力)→ ファイル →(入力) Program B

として複数のプログラムの入出力を ファイルを媒介して 繋げられる. しかし、その場でデータを受け渡す目的だけならばファイルを介するのは無駄だし遅い.

そこで, Program A の標準出力と Program B の標準入力を直接繋いでしまう方法 が unix には用意されている.

この同時リダイレクションとでもよぶべき方法は, 「パイプ」もしくは「パイプライン」と呼ばれ,次のように使う.

■ パイプの使い方 ■
sh 系, csh 系, fish 意味
コマンド1 | コマンド2 コマンド1 の標準出力を コマンド2 の標準入力に渡す.
コマンド1 |& コマンド2 コマンド1 の標準出力と標準エラー出力を
コマンド2 の標準入力に渡す.

注意: なお、パイプは好きなだけ何段にも重ねることができる!! ので覚えておこう.

  数学を学ぶ学生向けの説明:
・コマンド = データ列を別のデータ列へ変換する写像
・パイプ = 写像の合成
と思うとよいだろう.

パイプの実例

例えば, ps axu の結果を画面で見るとしよう. そのままこのコマンドを実行すると, 大量のデータが出力されて画面上を流れていってしまうのは経験しているだろう. こういうときは,less コマンドなどを用いて,一画面ずつ表示させるのが定石である. それには

1ps axu | less

↑ ps コマンドの出力と less コマンドの入力を直接パイプで繋いでいる

とすればよい.

さらに,この結果をプロセスの名前順に並べ直すことによって見易くしたいな〜 と思ったとしよう. すると,sort コマンドを使って,上の結果を並べ直せば良い. それにはどうするかというと,パイプを二回使って,

1ps axu | sort -k 11 | less

↑ ps コマンドの出力と sort コマンドの入力をパイプで繋ぎ,さらに sort コマンドの出力と less コマンドの入力をパイプで繋いでいる(パイプを二段使っている)

注意: ps コマンドの結果の何番目にプロセス名が表示されるかも環境に依存する.自分で数えてから 実行しよう.

とすれば,

1osboxes     1667  0.0  0.0 104232  4392 ?        S    18:09   0:00 (sd-pam)
2osboxes     1666  0.2  0.1  19384 11504 ?        Ss   18:09   0:01 /lib/systemd/systemd --user
3root         270  0.3  0.4  74192 39328 ?        S<s  18:09   0:01 /lib/systemd/systemd-journald
4root         721  0.0  0.1  24932  8420 ?        Ss   18:09   0:00 /lib/systemd/systemd-logind
5systemd+     511  0.1  0.0  16008  7188 ?        Ss   18:09   0:00 /lib/systemd/systemd-oomd
6  …略…

などと,プロセス名順に並んだ結果が画面上で一画面ずつ見られるというものだ.

  実習

  • 上に示した実例と同じ作業をやってみる.
  • さらに,パイプを三段使う例を考えて,実際に試してみよ.

tee

覚えておくと便利なコマンド tee ~ 出力を画面とファイルの両方に出力できる!

リダイレクションやパイプを使うときに, 「ファイルにも取っておきたいけど, 画面で確認しながら作業できないので不安だ」 という思いがあると思う.

こういう時便利なのが tee コマンドだ. 「標準入力を複製して,標準出力とファイルの両方に出力する」機能を持つ.

以下の実例を通じて解説しよう.

tee の実例

例として先の ls -lga の結果をファイルに収める例を考えてみよう.
この作業を先のやり方 ls -lga > file でやると, ''file'' の中身を見るまでどうなっているかわからない.

しかし,tee コマンドを用いて,

1ls -lga | tee sample-file

↑ ls コマンドの出力を標準出力に出しながら,かつ,sample-file というファイルにも出力する

とすると,結果は画面にも出力されつつ, sample-file という名前のファイルにも書込まれることになる.
慎重に作業を行ないたい,という時はこのコマンドを上手に使うのが良いだろう.

注意: 作業過程を記録しておく,という意味で似たようなものに script というコマンドがあることは紹介済みだ. どちらも使いこなし,適切に使い分けよう.



便利! 先読み評価(コマンド置換, command substitution)

ここで(少し早いが)、シェルが持つコマンド置換という便利な機能を紹介しておこう.

これは,コマンド中の ` (バッククォート, 逆引用符) や $( ) , もしくは () などで囲んだ部分を「先に実行してその結果で置き換える」というものである. これによって,コマンドの出力結果をあたかも文字列のように扱える.

簡単に言えば,通常ならば分けて行なう複数の操作を一行に書ける ということである.


注: bash では `` や $() で囲んだところにコマンド置換が適用されて,fish だと () で囲んだところに適用される.

先読み評価(コマンド置換)の実例

例えば,test-日付 という名前のファイルを作りたいな〜 と思ったとしよう(日付部分は月日の4桁とか).

日付を得るには,date コマンドが使えるのでこれを使わない手はない. これはオプションを適当に指定すれば好きな形式で出力が得られる便利なコマンドで、 例えば date +%m%d とすれば 4桁の数字の形で「月」「日」が得られる.

そこで,bash/dash の場合は

1touch test-`date +%m%d`

とするか、

1touch test-$(date +%m%d)

とする.fish の場合は

1touch test-(date +%m%d)

とする.

↑ date コマンドの出力結果が文字列となる

すると,コマンド置換によって, date +%m%d という部分が先に実行されて,結果の4桁の数字に置き換えられる ため,test-0505 などという空っぽのファイルが作られることになる.

注意: テンポラリファイルを作る専用のコマンド mktemp が存在する.何か実際に作業する際には結構便利なので覚えておこう.

注意: コマンド置換の応用で,「○○というプロセスを kill する簡単なコマンド」というようなものも作ることができる. わざわざ ps axu コマンドで調べて〜 とやらずに済むので楽だ. 詳しい学生は少し考えてみよう(grep や awk を使うとよいだろう).

先読み評価の実例をもう一つ

もうちょっと複雑な例も考えてみよう. 例えば,t で始まるファイル名をもつファイルが今のディレクトリにいくつあるかざっとみておきたい, と思ったとしよう. すると,ls コマンドと wc コマンド(単語数を数える)を用いて

1ls t* | wc -w

とすれば,該当するファイルが 3つあれば 3 という答えが得られる(ディレクトリがあるとまた話が変わるよ).

しかし,数字だけしか表示されないので味気ない. そこで,echo コマンド(文字列を表示する)と組み合わせて, bash/dash の場合は

1echo "`ls t* | wc -w` t* files exist."

とするか、もしくは

1echo "$(ls t* | wc -w) t* files exist."

として,fish の場合は

1echo (ls t* | wc -w) "t* files exist."

とすると,コマンド置換によって, ls t | wc -w* 部分が先に実行されて,結果の数字に置き換えられる ため,例えば

1  3 t* files exist.

などという結果が表示されるようになる.

注意: こういう場合,単数形と複数形が異なるので,正しい英語にしたかったら面倒だ(^-^).

  実習

  • ''tee'' コマンドと先読み評価に関して, 上に示した実例と同じ作業をやってみよう.



発展・補足編

基本編の内容に対する、発展・補足的な内容を以下に述べる.
学習初期においては無視しても良い内容として、授業時も解説を省略する予定である.

リダイレクションについて

標準入力を変更する [補足]

sh/csh 共通 fish の場合 解説
<< hoge
内容行1
内容行2

内容行最後
hoge
heredocs は shell に特別な規則を多く導入する「問題のある機能」なので fish では採用しない,とのこと. "heredocs"とよばれる syntactical sugar (糖衣構文). 標準入力を最初の ''hoge'' から次の ''hoge'' までの内容
に変更.
fish では代わりに

echo "\
内容行1
内容行2

内容行最後
" ¦ コマンド

などのように,パイプを使うことが推奨されている.
この際,最後のコマンドには "パイプからの入力を stdin として受け取れ" というオプションとしてオプション - を付ける必要があることがある.このオプションが必要かどうかはコマンドによって異なるのでコマンドのマニュアルを読むべし.

標準出力を変更するには [補足]

sh 系 csh 系 fish の場合 意味
(該当なし) (該当なし) >? hoge

注: noclobber 変数をセットしておくと、消去・上書きを防げる.
標準出力を hoge というファイルに変更する.
''hoge'' というファイルが存在しなければ作成する.
既に存在するならば内容は消去されて上書きされてしまう

>¦ hoge >! hoge (該当なし) noclobber 変数を無視して 標準出力の出力を hoge というファイルの末尾に追加していく.
(該当なし) (該当なし) >>? hoge

注: noclobber 変数をセットしておくと、消去・上書きを防げる.
標準出力の出力を hoge というファイルの末尾に追加していく.
''hoge'' が存在しなければ作成される.
(該当なし) >>! hoge (該当なし) noclobber 変数を無視して 上の動作を行う.

標準エラー出力を変更するには [発展]

標準エラーの出力先も変更できる.ややこしいのでこちらに掲載する.

sh 系 csh 系 fish の場合 意味
2> hoge (該当なし) sh系と同じ 標準エラー出力のみを ''hoge'' というファイルに変更.
noclobber 変数との関係は上記同様.
> hoge 2> boke

注: それぞれ個別に > を >> に変えても良い(その場合は追記になる).
(''コマンド'' > hoge ) >& boke

注は左と同じ.
sh系と同じ 標準出力を ''hoge'' というファイルに, 標準エラー出力を ''boke''
というファイルに各々変更.
noclobber 変数との関係は上記同様.
&> hoge

もしくは

> hoge 2>&1
>& hoge sh系と同じ 標準出力と標準エラー出力の出力を両方とも ''hoge'' というファイルに変更.
noclobber 変数との関係は上記同様.

なぜか sh/fish 系と csh系で使う文字が逆の並びなので要注意.
>¦ hoge 2>&1 >&! hoge (該当なし) noclobber 変数を無視して 標準出力/エラーの両方を ''hoge'' という
ファイルに出力.
&>> hoge

もしくは

>> hoge 2>&1
>>& hoge sh系と同じ 標準出力/エラーの両方を ''hoge'' というファイルの末尾に追加.
noclobber 変数との関係は上記同様.
(該当なし) >>&! hoge (該当なし) noclobber 変数を無視して 標準出力/エラーの両方とも ''hoge'' という
ファイルの末尾に追加.
(該当なし) (該当なし) 2>? や 2>>? , &>? , &>>? 等は noclobber 変数が設定されていれば動作しない.

覚えておくと便利なリダイレクト先 /dev/null [補足]

/dev/null ファイルの他の使い方として… 空っぽの新しいファイルを作れる.

1cp /dev/null  ファイル名

とすると,新しく空っぽのファイルが作られる. 新しくファイルを作成する方法としては,他に

1touch ファイル名

とするという方法もよく知られている.

注意: ファイルを作るには他にも様々なひねくれた方法が考えられる. いろいろ考えてみよ.

他にも,デバッグ情報などを常にエラー出力に出すことにしておいて, 不要なときはエラー出力先を ''/dev/null'' にしておく,という使い方や、実行結果には興味が無いが実行時間に興味があるのでファイルアクセスを減らしたい、というような場合にも使える.

別名(alias), 省略形(abbr) 設定 [発展]

エイリアス(alias) とは,コマンドに「別名」をつける機能である. 通常のシェルにはたいていついている機能で,簡単なわりに便利だ.

こういった話は分類すればシェルの設定に含まれるが,CUI を使う上でなにしろ便利かつ重要なのでここで先に紹介しておこう.

以下、例をあげよう.

まずは bash の場合だ.

文法は簡単だ.

1alias 別名='本来のコマンド'

とすれば良い.

これを実行すればそのセッションでそれ以降は別名が有効になるし,この設定が気に入ったならば設定ファイルに書き込んでおけば次のシェル起動時からはいつでも有効だ.

下記で bash での alias の例を見てみよう.

目的等 aliasサンプル
タイピングの手間を減らし,ミスを少なくする 例) alias md='mkdir'
としておいて、md dummy とすると
dummy ディレクトリが作れる.
他の例) alias em='emacs'
複雑な動作を 1コマンドに短縮する(新しいコマンドを作る) 例) alias newfile='touch dummy-$(date +%m%d)'
コマンドのオプションを指定するなどして,デフォルト動作を変更する 例) alias cp='cp -i'
例) alias mv='mv -i'
例) alias rm='rm -i'
例) alias man='jman'
例) alias ls='ls --color=auto -Fga'
変数を設定する 例) alias newpath='PATH=hogehoge'

次に fish の場合だ.

fish では別名(alias, コマンドに別の名前をつける)と省略形(abbr, 省略形で呼び出せ,実行時には展開されて元のコマンドが見える)の両方が使えるが,

省略形 abbr の方が利点が多く,おすすめ

だ.

  Youtube の動画に
  FISH (Friendly Interactive Shell) by Bash Boomer
というものがあり,fish の abbr が如何に便利かを主に説明しているので,ぜひ見ておくとよいだろう.

さて,文法はやはり簡単で,alias は

1alias 別名 本来のコマンド

とすれば良いし,abbr で省略形を追加する場合は

1abbr -a 省略形 本来のコマンド

とすれば良い. 他に詳しく知りたければ,たとえば

1help abbr

としてみよう.なんと web ブラウザにヘルプが出て(fish の特徴の一つ),細かいことまでわかるぞ.

さて,以下に例を挙げておこう.煩雑になるので,例としては abbr の方だけ書いておく.

目的等 abbr サンプル
タイピングの手間を減らし,ミスを少なくする 例) abbr -a md mkdir
としておいて、md dummy とすると
dummy ディレクトリが作れる.

他の例) abbr -a em emacs
複雑な動作を 1コマンドに短縮する(新しいコマンドを作る) 例)
abbr -a newfile touch dummy-(date +%m%d)
コマンドのオプションを指定するなどして,デフォルト動作を変更する 例) abbr -a cp cp -i
例) abbr -a mv mv -i
例) abbr -a rm rm -i
例) abbr -a man jman
例) abbr -a ls ls --color=auto -Fga
変数を設定する 例) abbr -a newpath PATH=hogehoge

alias, abbr の文法について一応のまとめ

alias, abbr の文法をまとめておこう.

alias 文法 (bashの場合)

機能 文法と解説
設定 alias 別名='コマンド'
ただし,引数参照はできない…はず.
解除 unalias 別名
表示 alias
関数設定 引数参照をしたいときは、alias の代わりに関数を使うと良い.
文法は以下のとおり.設定ファイルなどに書き込んで使う.

新関数名(){

内容… ;
内容… ;
}

この関数では、n 番目の引数を $n として参照できる.

alias文法 (csh系の場合)

機能 文法と解説
設定 alias 別名 'コマンド'

csh 系の場合,次のように書くと引数を alias 中で参照できる.
\!* (意味:全ての引数)
\!$ (意味:最後の引数)
\!:n (意味:n番目の引数)
解除 unalias 別名
表示 alias

abbr 文法 (fishの場合)

機能 文法と解説
設定 abbr -a 省略形 コマンド
解除 abbr -e 省略形
表示 abbr -s
なお,abbr -l でも良いがこちらは省略形のみが表示される.

  実習

  1. 上に示した abbr の例を一つで良いので実際に設定してみて,使ってみよう.その場で元のコマンドが展開される便利さ を味わってみよう.

  2. さらに,上に示した alias, abbr の例をなるべく多く試してみて,(余裕があれば)便利そうなものを以降に示す初期設定の方法を用いて初期設定せよ.

  3. (余裕がある者用) alias もしくは関数機能もしくは abbr を用いて,二つの引数の順番を逆にして表示するコマンド swap を作ってみよ.
    つまり, swap a b と入力すると, b a と表示されるような alias もしくは関数 swap を実現してみろ,ということである.



補足: シェルの設定等

自分に合わせてカスタマイズできるのが Unix のシェルの良いところだ. 以降,シェルの設定について一通り簡単に記しておこう.

ただし,よくわからなければ無理してカスタマイズしなくても良いわけなので,以降の補足情報はしばらくは無視しておく,というスタンスでも問題ないだろう.

シェルの設定ファイル [発展]

シェルおよびシェルから起動されるコマンドの動作の一部に影響を与える設定は, 以下のようなファイルの中に書いた設定で決まる.

sh 系の設定ファイル

ファイル名 解説
.bashrc bash を「非ログインシェルで対話的に」使う場合の設定を書くファイル.
下記の .bash_profile からも通常はこのファイルが読込まれる.
よって、端末設定とデフォルトコマンド起動以外はこのファイルに書込めばよい.
シェルの設定に関しては,通常はこのファイルをいじるだけで済むだろう.
.bash_profile bash を「ログインシェルで」使う場合の設定を書くファイル.
端末設定とデフォルトコマンド起動等をこのファイルで行なうのが正しい姿,だろう.
それ以外の設定は .bashrc を読込んで行なうようになっているのが普通.
.profile sh 系シェル共通に使える設定ファイル.
しかし,sh 系シェルを利用する人は現状では bash
を使う人が多いだろうから,
あまり出番はないだろう(^-^).
その他 .profile 中で変数 ENV に設定したファイルは対話環境では自動的に読込まれる.
しかしその機能を使う人は少ないか.

csh系の設定ファイル

ファイル名 解説
.tcshrc tcsh を使う場合,必ず読込まれるファイル.
環境によらず読込まれる.
共通に使える設定はこのファイルに書くと良い.
「端末設定とデフォルトコマンド起動」はこのファイルに書かないか,
環境を判定するやや複雑な設定を書くことになる.
まあ、普通はこのファイルを編集しているだけで済む.
.login ログイン時だけ,.(t)cshrc の読込みの後に読込まれるファイル.
端末設定とデフォルトコマンド起動はこのファイルに書込むのが良い.
詳しいことが分からないウチは触らない方がよいだろう.
.cshrc csh 系シェル共通に使える設定ファイル.
.tcshrc の代わりに使う人も多い.
その他 .tcshrc 中などで source コマンドを用いて別ファイルを読込む設定にすることも多い.
具体的には,alias コマンドだけを別ファイルにするなどの設定がよく見られる.

fish の設定ファイル

ファイル名 解説
~/.config/fish/config.fish fish が起動されるときに読込まれるファイル.
なかったら作ることも可.
もっと詳しく知りたかったら,fish に対して,"help" 1 とコマンドをいれてみよう.

変数の設定: シェル変数 [発展]

シェルが固有に持つ変数をこう言う. シェル自身の動作にかかわる設定に用いられる. 名前は小文字で記述することが多い. 使い方等は以下のとおり.

意味 sh系 csh系 fish
作成, 代入 変数名=値 set 変数名=値 set 変数名 値
削除 unset 変数名 同左 set -e 変数名
表示 set 同左 同左
参照 $変数名 同左 同左

代表的なシェル変数

シェルがもつ独自の変数、シェル変数のうち、少しだけ紹介しておこう.

シェル変数 解説
PATH
(コマンドサーチパス)
コマンドを起動するときに,
どのディレクトリから探してくるのかをシェルに教えておくもの.
path に設定されているディレクトリにあるコマンドは,
コマンド名を入力するだけで使用できる.

よくわからないうちは追加のみを行うようにしておこう.

Windows にも同じ名前で同じ機能をもつ環境変数がある.
PS1: sh系, prompt: csh 系
(プロンプト)
コマンド入力行の先頭部分にシェルが表示する文字列のこと.
bash では例えば,
PS1="(BAsh)\H<\u>\[\033[1;34m\]\w\[\033[0m\] <\!>"
と入力すると、プロンプトがこの設定通りに変化する.
これをファイル .bashrc の中に記述して
source .bashrc
と入力するかログインし直しても良い.
HISTSIZE: sh系, history: csh系
(ヒストリ)
シェルが履歴(history)を取っておくコマンドの数.
少し多めにしておくとよいだろう.
ignoreeof, noclobber,noglob 等
(エラー処理,安全化系)
うっかりミスや知識不足によって発生する支障を予防する.
オンラインマニュアルで調べておこう.

もう少し詳しく知りたければ、 man bash もしくは man tcsh として,シェル変数の項目を読めばよい. びっくりするぐらいたくさんあるぞ.

変数の設定: 環境変数 [発展]

シェルから起動されるコマンドの動作設定にかかわる変数をこういう. シェルだけでなく、いろんなコマンドが参照する前提だ. 名前は大文字で記述することが多い. 使い方等は以下のとおり.

意味 sh系 csh系 fish
作成, 代入 (シェル変数として作成した後) export 変数名
もしくは、合わせて1行で export 変数名=値 としてしまう方が良いかも.
setenv 変数名 値 set -x 変数名 値
削除 unset 変数名 unsetenv 変数名 set -e 変数名
表示 set or env printenv set
参照 $変数名 同左 同左

代表的な環境変数

環境変数 解説
HOME
(ホームディレクトリ)
ユーザのホームディレクトリ.
Unix の場合はアカウント作成時に事実上設定されるので、いじらなくて良い.
Windows では自分で設定したほうが幸せになれるだろう.
EDITOR
(エディタ)
デフォルトのエディタ.
設定しておかないとおそらく vi が起動するので,
emacs あたりを設定しておくのがよい.
PAGER
(ページャ)
デフォルトの画面表示ソフト.
日本語に対応したものを設定しておくのがよい.
LANG
(言語)
デフォルトの言語.
プログラムがこの環境変数を見て適切に設定を変えてくれることがある.
C に設定しておくと無難だが、もちろん英語表記になる.
日本語を用いるならば,
Linux やFreeBSD では ja_JP.UTF-8ja_JP.eucJP などと設定すればよい.
TERM, TERMCAP
(端末属性)
端末の名前や性質を指定する.
何か設定しなければいけないという状態に追い込まれたら(^-^),
TERM に vt100 を設定しておけばとりあえずしのげるだろう.

設定ファイル修正の注意 [発展]

シェルの設定ファイルを修正して,その効果をみるためにはどうしたらよいだろうか? いったんログアウトしてまたログインする? それは「危険」だ.

シェルの設定ファイルの修正中は絶対にログアウトや exit をするな!
修正に失敗すると二度とログインできなくなることがあるので、設定のミスが無くなるまでログアウトしないようにしよう.
もしそうなったら… 管理者に泣きつけばなんとかなるとは思うが…

シェルの設定ファイルを修正する時は、以下のように行動しよう.

  1. (後述の) source コマンドで設定ファイルが読み込まれたときの反応をしっかり確認する
  2. カスタマイズが終わるまで絶対にログアウトしない端末を一つは確保しておく
  3. 何か設定を変えたら別の端末(ソフト)からログインしてテストする(= 現在の端末(ソフト)はログアウトしない)

設定ファイルの読み込みコマンド: source [発展]

設定ファイルを修正した後,その場でその影響をみようとして「設定ファイルを読み込む」には,

1source ファイル名

とすればよい.
例えば、設定ファイルである .bashrc ファイルを読み込みたければ、

1source ./.bashrc

とする.
注意: セキュリティ対策の一環で、.(ピリオド)で始まるファイル名は直に指定すると無視される設定になっていることが多い. つまり、

1source .bashrc (← たぶん動かない)

とすると「そんなファイルは無いぜ」と言われてエラーになったりする. そのため、上では ./ をファイル名の前につけて source コマンドを使っている( . は「今居るディレクトリ」という意味).

注意: なお、素の sh は source コマンドが使えず,

1. ファイル名  (=ピリオド,空白, ファイル名)

という方法しか使えないそうだが…現在はもう気にしなくて良いだろう.

  実習

  1. 上に示した例をみながら,emacs などで ~/.bashrc ファイルを編集し,プロンプトだけでも変更してみよ.

    ~/.bashrc ファイルがそもそも無い場合は,touch コマンドなどで ~ ディレクトリにファイルを作ってから設定を書き込めば良い( ~ はユーザのホームディレクトリ).
    具体的には、 cd ~ ; touch .bashrc などとすればいいだろう.

  2. 余裕のある者はさらに,シェルのオンラインマニュアルなどを参考にしていろいろ設定してみよう.

デフォルトコマンド起動 [発展]

bash ならば .bash_profile で, csh 系ならば .login で,ログイン時に起動されるコマンドを書いておく, ということもできる.

これをうまく使って,例えば起動時に

  • ディスクの(自分の)使用量を調べる.
  • メールが来ているか調べる.
  • 今日の運勢を占う(^-^).
  • ○○さんが大学のマシンにログインしているか調べる.
  • やらないといけない仕事を表示する(ToT)

などということができる. まあ,今時はこれらの機能はそんなにありがたくないが、知っていると助かることもあるだろう.

  実習

  • ログインするたびに, You use xxx MB in this system. という感じで, ユーザ個人のディスク使用量が表示されるようにしてみよう.
    なお,du というコマンドを使うと良い. ただし,オプションは慎重に設定しよう.

  1. fish に対して "help" と打つとなんと web browser でマニュアルを見せてくれる.初めて見るときにはちょっと驚くぞ. ↩︎

レポート No.4

  注意

近年はセキュリティ上の懸念から,実行形式のプログラムなどをメールに添付するとそのメールそのものの受信を受信側サーバが拒絶したりする. そういうことを避けるため,レポートをファイルで提出するときはそういった懸念のあるファイル形式のものではないようにしよう.

まあ要するに,レポートは pdf ファイルにして送るのが良い ということだと思っておこう.

以下の課題について、自らの将来のスキルアップに繋がるように調査と考察を行い,
     学籍番号-氏名-04.pdf
というファイルとしてレポートを作成し、  webフォーム から教官宛に提出しよう.

なお,レポートを $\TeX$ 等で作成したものを印刷した「紙媒体」を教官に直接手渡す形で提出してもよいが、物質によるレポート提出は常に破損や紛失の可能性があるのであまりお勧めはしないぞ.

  1. 本資料の「基本編」の実習部分を行い,それについて報告せよ.
    なお、レポートには以下の内容を含めよう.
  • 「自分で方法を考えよ」という課題の入った実習については、「どのような方法を考案したか」の解説.
  • 実行したコマンド列
  • そのとき観察された出力
  • うまく作業できたか or 失敗した(エラーが出た) かの解析.
  • 失敗した場合のリカバリーについて.

  1. パイプと組み合わせて上手に使うと便利そうなコマンドを紹介せよ.

    なお、「発展・補足編」を読む余裕の有った者は、下記の課題にも挑戦してみると良い

  2. alias もしくは abbr を用いて便利な 別名/短縮 コマンドを自分なりに考えてみよう.可能ならばそれらをいつも使えるようにシェルの設定ファイルに書き込もう.

  3. 「今日の日記を書くためにエディタが起動する」コマンドを自分で作成・組み合わせる などして用意せよ.
    具体的には,その日の日付がついたテキストファイルをエディタが開くという程度でよい.

  4. シェルのプロンプト設定を「便利になるように」設定せよ.
    とくに fish を使う場合はかなり「かっこよく?」できるので,いろいろ試してみると良い.