MacBookのターミナルの操作と設定

OSX 10.5以降では、何もしなくてもターミナルは日本語を表示してくれる。これまでデフォルト設定のまま問題なく使えていたので、無関心になりがちだった。でも、改めて操作方法や設定を調べ直すと、便利な操作や設定があることに気付かされる。そして、新たな操作や設定を知ることは、シェルやコマンドの仕組みを覚えることに繋がる。きっと、まだまだ自分の知らない多くの技が眠っているはず。

作業環境

$ bash --version
GNU bash, version 3.2.48(1)-release (x86_64-apple-darwin10.0)
Copyright (C) 2007 Free Software Foundation, Inc.

ターミナルの操作

クリア
  • command-K、あるいはcontrol-Lで、ターミナル画面のクリア。(ほぼ同等だが、微妙にクリアされる範囲が違う)
入力補完
  • コマンド入力中にtabキーを押すと、入力補完される。
    • 複数候補がある場合は警告音が鳴る。
    • もう一度tabキーを押すと、候補リストが表示される。
    • あるいは次の文字も入力して、tabキーを押してみる。(絞り込まれて補完されるかも)
  • escキーのダブル押しで、tabキー1回と同様の入力補完が期待できる。
    • もう一度escキーをダブル押しすると、候補リストが表示される。
全コマンド一覧
  • ターミナル画面を表示して esc キー長押しすると...(bashの場合)
  • Display all 1812 possibilities? (y or n)と出るので y を押すと、1812コマンドが一覧表示された!
$ 
Display all 1812 possibilities? (y or n)
!                         done                      join                      perlbug5.8.9              sqlite3
./                        dot_clean                 josusi_dic_find           perlcc                    sqlite3_3_4_0
2to3                      dprofpp                   jot                       perlcc5.8.9               srm
2to32.6                   dprofpp5.10.0             jpeg2swf                  perldoc                   ssh
:                         dprofpp5.8.9              jpegtran                  perldoc5.10.0             ssh-add
AppleFileServer           drutil                    jps                       perldoc5.8.9              ssh-agent
BMPtoRGB                  dscacheutil               jrunscript                perlivp                   ssh-keygen
BootCacheControl          dscl                      jsadebugd                 perlivp5.10.0             ssh-keyscan
BootstrapDump             dsconfigad                jstack                    perlivp5.8.9              sshd
BuildStrings              dsconfigldap              jstat                     perlthanks                sso_util
...(中略)...
矩形(長方形)領域のテキストを選択してコピーする
  • optionキーを押しながら、マウスでドラッグしてテキスト範囲を選択する。
コマンド履歴
  • ↑↓矢印キーでコマンド履歴を辿れる。
スクロール
Command-↑・↓ 上スクロール・下スクロール
fn-↑・↓ ページアップ・ページダウン
fn-←・→ ページ上端までスクロール・ページ下端までスクロール
コマンド入力中の操作
option-クリック クリック位置にマウスカーソルを移動する
control-A・E カーソルを行頭へ移動・カーソルを行末へ移動
control-K・U カーソル位置から行末まで削除する・カーソル位置から行頭まで削除する
control-W・option-D カーソル左側の次のスペース手前まで削除する・カーソル右側の次のスペース手前まで削除する 単語単位の削除
control-Y 削除したテキストをペーストする
control-F・B 1文字右へ移動・1文字左へ移動
option-F・B*1 1単語右へ移動・1単語左へ移動 単語単位の移動
ディレクトリの移動
  • zariユーザでログイン
$ cd          # ホームへ移動(/Users/zari)
$ cd ~guest   # Guestユーザへ移動(/Users/Guest)
$ cd ~        # ホームへ移動(/Users/zari)
$ cd desktop  # デスクトップへ移動(/Users/zari/desktop)
$ cd -        # 一つ前のディレクトリへ戻る(/Users/zari)
$ cd ..       # 一つ上のディレクトリへ移動(/Users)
$ cd .        # 現在のディレクトリへ移動(/Users) 

bashの設定ファイル

  • ~/.bash_profile の例
# ~/.bashrcの内容を読み込むだけ
if [ -f ~/.bashrc ]; then
  . ~/.bashrc
fi
  • ~/bashrc の例
# コマンドプロンプトの設定
PS1='\[\033[40;1;32m\]\u\[\033[2;32m\]@\[\033[0m\]\[\033[40;32m\]\h \[\033[1;36m\]\w \[\033[0m\]\[\033[40;2;37m\]\d  \t\[\033[0m\]\n\\$ '

# コマンドサーチパスの追加
# MacPortsのパスを追加
PATH=/opt/local/bin:$PATH

# エイリアスの設定
alias ls='ls -aF'
alias rm='rm -i'
alias mv='mv -i'
alias cp='cp -i'
alias ..='cd ..'
alias ...='cd -'
alias cot='open -a CotEditor'
alias screensaver='/System/Library/Frameworks/ScreenSaver.framework/Resources/ScreenSaverEngine.app/Contents/MacOS/ScreenSaverEngine'

# 関数の読み込み
. /usr/local/bin/saykanji.sh

# シェルオプションの設定
# *ワイルドカードで、.不可視ファイルにもヒットする設定
#   $ ls *bash*
#   .bash_history  .bash_profile  .bashrc
shopt -s dotglob
コマンドプロンプトの設定

コマンドプロンプトは奥が深い...。

  • Visorスタイルのターミナルにすると、同色の黒い背景は淡いグレーで表現された。
# 半角¥は、半角\に置き換える。
$ echo "PS1='$PS1'";\
> echo "PS2='$PS2'";\
> echo "PS3='$PS3'";\
> echo "PS4='$PS4'";
PS1='\[\033[40;1;32m\]\u\[\033[2;32m\]@\[\033[0m\]\[\033[40;32m\]\h \[\033[1;36m\]\w \[\033[0m\]\[\033[40;2;37m\]\d  \t\[\033[0m\]\n\\$ '
PS2='> '
PS3=''
PS4='+ '

$ PS3='Number? '
$ select VALUE in A B C; do echo "'$VALUE' is selected.";break; done
1) A
2) B
3) C
Number? 1
'A' is selected.

$ unset PS3
$ select VALUE in A B C; do echo "'$VALUE' is selected.";break; done
1) A
2) B
3) C
#? 2
'B' is selected.
  • PS1は、コマンド待ちの状態で表示される、最も多く目にするプロンプト。
  • PS2は、コマンド入力中、入力完了まで複数行にわたる場合に表示されるプロンプト。
  • PS3は、コマンド実行中、selectコマンドで番号の選択を求める場合のプロンプト。
    • PS3のデフォルトは未設定だが、'#?'が表示される。
    • PS3=''と設定してしまうと、何も表示されない。
    • unset PS3とすることで、デフォルト設定に戻る。
  • PS4は、シェルスクリプトをトレースオプション-xで実行中に表示されるプロンプト。
    • サブシェルの深さに応じて、プロンプトの最初の文字が2重、3重に重なる。
# ---------- ファイル:~/desktop/sample.sh ----------
#!/bin/bash
echo this is sample.
echo `date`
$ bash -x ~/desktop/sample.sh
+ echo this is sample.
this is sample.
++ date
+ echo 2010年 $'2?\234\21021?\227?' $'?\227??\233\234?\227?' $'22?\231\20203?\210\20606?\222' JST
2010年 2月21日 日曜日 22時03分06秒 JST
  • エスケープシーケンス

\a ASCII のベル文字 (07)
\d "曜日 月 日"のフォーマットによる日付け(例 "Tue May 26")
\e ASCII のエスケープ文字 (033)
\h 最初の"."のところまでのホスト名
\H ホスト名
\n 改行
\r 復帰
\s シェル名、$0 のベース名(最後のスラッシュの後ろの部分)
\t 24時間制の HH:MM:SS のフォーマットによる時間
\T 12時間制の HH:MM:SS のフォーマットによる時間
\@ am/pm をつけた12時間制のフォーマットによる時間
\u 現ユーザーのユーザー名
\v bash のバージョン(例 2.00)
\V bash のリリース番号、バージョンとパッチレベル(例 2.00.0)
\w 現在のディレクト
\W 現在のディレクトリのベース名
\! 現在のコマンドのヒストリー番号
\# 現在のコマンドのコマンド番号
\$ UIDが0なら#、そうでなければ$
\nnn 8進数nnnに対応する文字
\\ バックスラッシュ
\[ 表示されない文字列の開始。端末制御シーケンスをプロンプトに埋め込む。
\] 表示されない文字列の終り。

      • 半角¥は、半角\に置き換える。
  • コマンドの実行結果をプロンプトにする。
# 半角¥は、半角\に置き換える。
$ PS1='$(date +%Y-%m-%d\ %H:%M:%S) $ '
2010-02-20 21:44:00 $

背景色 文字色
40 30
41 31
42 32
43 33
44 34
45 35
46 36
47 37

# 半角¥は、半角\に置き換える。
$ PS1="\[\033[41;32m\] RED & GREEN \[\033[0m\] $ "

  • 文字スタイル

1:明、2:暗、4:下線、5:点滅、7:逆転、8:非表示、0:全設定クリア(背景色・文字色・スタイル)

# 半角¥は、半角\に置き換える。
$ PS1="\[\033[2;40;32m\] DARK \[\033[0;40;32m\] NORMAL \[\033[1;40;32m\] LIGHT \[\033[0;4;40;32m\] UNDERLINE \[\033[0;7;40;32m\] REVERSE \[\033[0m\] $ "


shopt(shell option、シェルオプション)コマンドによる設定
  • shoptコマンドを引数なしで実行すると一覧が表示される。
その他のシェル変数
# 環境変数の一覧
$ printenv

# 環境変数、シェル変数、関数の一覧
$ set

ログインシェルの変更

システム環境設定から
  1. システム環境設定 >> アカウント を開く。
  2. ウィンドウ左下の鍵アイコンをクリックして、変更可能な状態にする。(解錠されていればOK)
  3. マイアカウントをcontrol-クリックして、詳細オプション... を開く。
  4. ログインシェル:の項目でリストを選択する。(その他の項目を意味が分からずに変更してしまうと、アカウントを消失する可能性もあるので十分注意が必要)
リストにログインシェルを追加する
  • 自分でインストールしたシェルは、そのままではシステム環境設定 >> アカウントのログインシェル:の項目に表示されない。
  • root権限でテキストファイル/etc/shellsを開いて、そこにインストールしたシェルのパスを追加する。
$ sudo vi /etc/shells
# List of acceptable shells for chpass(1).
# Ftpd will not allow users to connect who are not using
# one of these shells.

/bin/bash
/bin/csh
/bin/ksh
/bin/sh
/bin/tcsh
/bin/zsh
# ここにインストールしたシェルのパスを追加する
chpassコマンド
  • ログインシェルは、chpassコマンドで変更することもできる。
  • ログインシェルとして指定できるのは、上記/etc/shellsに書かれているシェルだけ。
$ chpass -s /bin/zsh
      • ちなみに、引数なしでchpassコマンドを実行すると、エディタ*2が起動して、設定ファイルが開く。(その他の変更可能なユーザ情報を確認できる)
      • 変更して保存終了すれば、その内容にユーザ情報が変更される。

Visor

ターミナルの使い勝手を向上してくれる。使い始めると手放せない便利さを感じる。

  • controlキーを2度押しすると、ターミナルが下からスライドするように表示される。
    • ショートカットやターミナルの表示位置は、自分好みに設定できる。
    • 必要な時だけ、常に同じ位置に同じサイズで表示されるところが良い。
    • もちろんタブも使えて、ウィンドウに切り離したり、結合もできる。
  • Copy on Selectのチェックを入れると...
    • 選択したテキストを自動コピーしてくれる。(Command-V不要)
    • 選択したらCommand-Vで貼り付けるだけでOKになる。

TotalFinder

以前から、Finderのファイルをコピーすれば、ターミナルにはファイルパスとしてペーストできた。ターミナルはFinderと連携させることで、より快適になる。

  • Finderをタブ管理できるようになる。
  • optionキーを2度押しすると、Finderが下からスライドするように表示される。(Visorのように)
  • ウィンドウに切り離したり、結合もできる。

タブで管理できるFinderって素晴らしく便利だ。ターミナルさえタブを利用できるようになったのに、OSX標準のFinderで利用できないのは疑問を感じていた。しかも、Visorのような邪魔にならない使い勝手。ウィンドウやスペースを探し回らすに、欲しい時に常に同じ場所で直ぐ操作できる。Exposé・Spacesの上を行く。

OS・シェル・ターミナルの関係について

MacBookのターミナルからコマンドを使い初めの頃、OS・シェル・ターミナルの区別が曖昧な自分がいた。


かつて、まだパソコンという考えもなく、コンピュータと言えば、メインフレームと呼ばれる大型のマシンが当り前だった時代の話。

  • 非常に高価なメインフレームは、企業や大学・研究所単位で数台しか所有できず、1台をみんなで共有して利用するのが当り前だった。
  • メインフレームを利用するには、ケーブルやネットワークを介して接続された「端末」と呼ばれるマシンを使っていた。
  • 端末はキー入力と画面出力の機能しか持たず、メインフレームに比べたら非常に安価。
  • 端末に入力した情報をメインフレームに送って、処理の結果を受け取って画面に表示していた。(メインフレームファイルシステム側に出力することもあると思う)

メインフレームは、UNIXと呼ばれるOSで制御されていた。

  • OSは、必要最小限の機能しか提供してくれない。(適切なメモリを割り当て、適切なタイミングで、複数のプログラムを実行したり、ファイルへの読み書きを管理するなど)
  • OSが理解できるのは定義されたシステムコールだけであり、毎回プログラムを書いてシステムコール*3の連続で操作するのは、とても実用的とは言えない状態だ。

そこで、「シェル」と呼ばれるプログラムが、人間とOSの仲介をしてくれる仕組みになった。

  • シェルは、一般的な英単語や略語・記号を解釈して、ファイルの操作やプログラムの実行をOSに依頼する。
  • 利用頻度の高いプログラムは、コマンドとして、数文字のテキスト入力で実行できるようになった。
  • 処理結果は、画面に表示したり、ファイルに保存したり、次のコマンドに渡すことだってできる。
  • こうしてコンピュータは、シェルによって対話的*4に利用できるようになったのである。

時代は移り変わり、コンピュータは劇的に安価になり、一人1台、持ち運べるノートパソコンが当り前の環境になりつつある。もはや、端末は不要になった*5

  • ずいぶん時間が経過したにもかかわらず、今使っているMacBookさえも、当時のメインフレームから脈々と受け継がれてきたUNIXというOSで制御されている。
  • そして、シェルや端末もまた、MacBookの中で生き続けている。
  • かつての端末は「ターミナル」というアプリケーションによって、GUI環境のウィンドウの中でエミュレーションされるようになった。
  • シェルも改良され、いくつかに派生して進化した。MacBookには6種類(bash csh ksh sh tcsh zsh)のシェルがインストールされていた。
  • かつての端末と同じく、ターミナルもあらゆるUNIX環境に接続できる。
  • その操作感は、接続先のシェルが提供する機能によって変化する。
  • ターミナルは、あくまでキー入力と画面表示に特化した「端末」なのだ。

MacBookの見た目はだいぶ派手になったが、それはGUI*6の部分である。

  • 一方、昔ながらのシェル(bashなど)が提供するのは、すべてが文字による操作で、CUI*7と呼ばれる。
  • そう考えると、OSXが提供するFinderが作り出すデスクトップ環境も、シェルの一種と言える。
  • OSは、コンピュータを制御する最も基本的な仕組みを提供する。
  • シェルは、そのOSを対話的に利用できる操作環境を提供する。
  • ターミナルは、キー入力をシェルに届けて、処理結果をシェルから受け取り、画面に表示する。

*1:ターミナル >> 環境設定... >> 設定 >> キーボード >> メタキーとしてoptionキーを使用 チェックありの状態

*2:例:vi。保存しない終了方法:esc、:q!、return。

*3:実際にはプログラミング言語の標準ライブラリの関数を利用することになると思うので、その関数の中からシステムコールされることになる。

*4:コマンドを手順に沿って書き出し、テキストファイルとして保存しておき、そのファイルをシェルが実行する非対話的な利用方法もある。

*5:別の視点から見ると、かつてのメインフレームの性能を軽く超えるノートパソコンが、インターネット端末になりつつある。端末は不要になったのではなく、パソコンが端末になってしまったのである。

*6:グラフィカル・ユーザー・インタフェース。マウスでメニューやボタンなどの現実感のある画像を操作して、コンピューターを利用する仕組み

*7:キャラクタ・ユーザー・インタフェース