#ライセンスとクレジット
クレジット
https://missing.csail.mit.edu/2020/command-line/
ライセンス
https://creativecommons.org/licenses/by-nc-sa/4.0/
講義動画
https://www.youtube.com/watch?v=e8BO_dYxk5c
Todo
#コマンドライン環境
この講義では、シェルを使用する際のワークフローを改善するためのいくつかの方法を紹介します。
これまでシェルを使ってきましたが、主にさまざまなコマンドを実行することに焦点を当ててきました。
ここでは、複数のプロセスを追跡しながら同時に実行する方法、特定のプロセスを停止または一時停止する方法、プロセスをバックグラウンドで実行する方法について説明します。
また、エイリアスを定義したり、ドットファイルを使って設定したりすることで、シェルやその他のツールを改善するさまざまな方法についても学びます。
これらの方法は、長いコマンドを入力しなくても、すべてのマシンで同じ設定を使用することができるなど、時間の節約につながります。
ここでは、SSH を使ってリモートマシンを操作する方法を見ていきます。
#ジョブの制御
例えば、コマンドの実行に時間がかかりすぎている場合(非常に大きなディレクトリ構造を検索するfind
など)、実行中のジョブを中断する必要がある場合があります。
ほとんどの場合、Ctrl-C
を押すと、コマンドが停止します。
しかし、実際にはどのように動作するのでしょうか。
また、なぜプロセスの停止に失敗することがあるのでしょうか。
##プロセスの停止
あなたのシェルは、シグナルと呼ばれるUNIXの通信メカニズムを使って、プロセスに情報を伝えています。
プロセスはシグナルを受け取ると、実行を停止し、シグナルを処理し、シグナルが伝えた情報に基づいて実行の流れを変える可能性があります。
このような理由から、シグナルはソフトウェアの割り込みである。
今回の例では、Ctrl-C
を入力すると、シェルがプロセスにSIGINT
シグナルを配信するように促します。
ここでは、SIGINT
を捕捉し、それを無視して、もはや停止しないPythonプログラムの最小限の例を示しています。
このプログラムを終了させるには、Ctrl-\
を入力することで、代わりにSIGQUIT
シグナルを使用することができます。
#!/usr/bin/env python
import signal, time
def handler(signum, time):
print("\nI got a SIGINT, but I am not stopping")
signal.signal(signal.SIGINT, handler)
i = 0
while True:
time.sleep(.1)
print("\r{}".format(i), end="")
i += 1
このプログラムに SIGINT
を 2 回送り、その後に SIGQUIT
を送るとどうなるかを示します。
なお、^
はターミナルで入力されたときの Ctrl
の表示方法です。
$ python sigint.py
24^C
I got a SIGINT, but I am not stopping
26^C
I got a SIGINT, but I am not stopping
30^\[1] 39913 quit python sigint.py
SIGINT
とSIGQUIT
は通常、ターミナル関連の要求に関連していますが、プロセスの潔白な終了を要求するより一般的なシグナルはSIGTERM
シグナルです。
このシグナルを送信するには、kill
コマンドを使います。
kill -TERM <PID>
##プロセスの一時停止とバックグラウンド化
シグナルはプロセスをkill
する以外にも様々なことができます。
例えば、SIGSTOP
はプロセスを一時停止します。
ターミナルで Ctrl-Z
を入力すると、Terminal Stop(ターミナルストップ)
の略である SIGTSTP
シグナルを送信するようにシェルが促します(つまりターミナル版の SIGSTOP
)。
一時停止したジョブをフォアグラウンドで続行するには fg
を、バックグラウンドで続行するには bg
をそれぞれ使用します。
jobs
コマンドは、現在の端末セッションに関連する未完了のジョブを一覧表示します。
これらのジョブはpid
で参照することができます(pgrep
で調べることができます)。
より直感的には、パーセント記号の後にジョブ番号(jobsで表示)を付けてプロセスを参照することもできます。
最後にバックグラウンドで実行されたジョブを参照するには、特別なパラメータ$!
を使用します。
もうひとつ知っておいていただきたいのは、コマンドの中に「&
」というサフィックスをつけると、そのコマンドがバックグラウンドで実行され、プロンプトが戻ってきます。
既に起動しているプログラムをバックグラウンドにするには、Ctrl-Z
に続いて bg
を実行します。
バックグラウンドになったプロセスは、まだターミナルの子プロセスであり、 ターミナルを閉じると死んでしまうこと
に注意してください (これにより、さらに別のシグナル SIGHUP
が送られます)。
これを防ぐには、nohup (SIGHUP を無視するラッパー)
を使ってプログラムを実行するか、プロセスがすでに開始されている場合は disown
を使います。
また、次のセクションで説明するように、ターミナルマルチプレクサを使用することもできます。
以下に、これらのコンセプトの一部を紹介するサンプルセッションを示します。
$ sleep 1000
^Z
[1] + 18653 suspended sleep 1000
$ nohup sleep 2000 &
[2] 18745
appending output to nohup.out
$ jobs
[1] + suspended sleep 1000
[2] - running nohup sleep 2000
$ bg %1
[1] - 18653 continued sleep 1000
$ jobs
[1] - running sleep 1000
[2] + running nohup sleep 2000
$ kill -STOP %1
[1] + 18653 suspended (signal) sleep 1000
$ jobs
[1] + suspended (signal) sleep 1000
[2] - running nohup sleep 2000
$ kill -SIGHUP %1
[1] + 18653 hangup sleep 1000
$ jobs
[2] + running nohup sleep 2000
$ kill -SIGHUP %2
$ jobs
[2] + running nohup sleep 2000
$ kill %2
[2] + 18745 terminated nohup sleep 2000
$ jobs
特別なシグナルとしてSIGKILL
があります。
これはプロセスがキャプチャできないため、常にプロセスを直ちに終了させることができます。
しかし、ゾンビとなった子プロセスを残してしまうなどの悪い副作用があります。
これらのシグナルやその他のシグナルについては、ここで詳しく説明していますし、man signal
やkill -t
と入力することもできます。
#ターミナルマルチプレクサ
コマンドラインインターフェイスを使用していると、複数のものを同時に実行したくなることがよくあります。
例えば、エディタとプログラムを同時に実行したい場合などです。
これを実現するには、新しいターミナルウィンドウを開く必要がありますが、ターミナルマルチプレクサを使用する方がより汎用的なソリューションです。
tmux
のようなターミナルマルチプレクサは、ペインやタブを使ってターミナルウィンドウを多重化することができ、複数のシェルセッションを操作することができます。
さらに、ターミナルマルチプレクサを使えば、現在のターミナルセッションを切り離して、後から再接続することもできます。
これにより、リモートマシンで作業する際に、nohup
などのトリックを使用する必要がなくなり、ワークフローが大幅に改善されます。
最近、最も人気のあるターミナルマルチプレクサはtmux
です。
tmux
は高度な設定が可能で、関連するキーバインドを使用することで、複数のタブやペインを作成し、それらを素早くナビゲートすることができます。
tmux
はあなたがそのキーバインドを知っていることを期待しており、それらはすべて <C-b> x
という形をしています。
これは (1) Ctrl+b
を押し、(2) Ctrl+b
を離し、(3) x
を押すことを意味します。
-
Sessions
:セッションとは、1つまたは複数のウィンドウを持つ独立したワークスペースのことです。-
tmux
は新しいセッションを開始します。 -
tmux new -s NAME
は、その名前でセッションを開始します。 -
tmux ls
は現在のセッションの一覧を表示します。 -
tmux
の中で<C-b> d
と入力すると、現在のセッションを切り離します。 -
tmux a
は最後のセッションをアタッチします。t
フラグを使用して、どのセッションを切り離すかを指定できます。
-
-
Windows
- エディタやブラウザのタブに相当し、視覚的には同じセッションの別の部分となります。-
<C-b> c
新しいウィンドウを作成します。これを閉じるには、 を実行しているシェルを終了させればよい。 -
<C-b> N
N番目のウィンドウに移動します。番号が付いています -
<C-b> p
前のウィンドウに移動します。 -
<C-b> n
次のウィンドウに移動します。 -
<C-b> ,
現在のウィンドウの名前を変更する -
<C-b> w
現在のウィンドウを一覧表示
-
-
Panes
-vim
の分割と同様に、ペインでは複数のシェルを同じビジュアルディスプレイに表示することができます。-
<C-b> "
現在のペインを水平方向に分割します。 -
<C-b> %
現在のペインを垂直方向に分割 -
<C-b> <direction>
指定された方向にあるペインに移動します。ここでいう方向とは、矢印キーを意味します。 -
<C-b> z
現在のペインのズームを切り替えます。 -
<C-b> [
スクロールバックを開始します。その後、で選択を開始し、でその選択範囲をコピーすることができます。 -
<C-b> <space>
ペインの配置を循環させます。
-
memo
tmuxのショートカットは変更できます.個人的に常用するペインの水平垂直分割をそれぞれ-
,|
を使うと,使い始めは楽でおすすめです.
さらに、tmux
についての簡単なチュートリアルと、オリジナルのscreen
コマンドについてのより詳細な説明があります。
また、ほとんどのUNIXシステムにインストールされているscreen
についても理解しておくとよいでしょう。
https://www.man7.org/linux/man-pages/man1/screen.1.html
#エイリアス
多くのフラグや冗長なオプションを含む長いコマンドを入力するのは面倒なことです。
そのため、ほとんどのシェルはエイリアスをサポートしています。
シェルのエイリアスとは、他のコマンドを短く表現したもので、シェルが自動的に置き換えてくれます。
たとえば、bashのエイリアスは次のような構造になっています。
alias alias_name="command_to_alias arg1 arg2"
なお、等号「=」の周りにはスペースがありませんが、これはエイリアスが単一の引数を取るシェルコマンドだからです。
エイリアスには便利な機能がたくさんあります。
# Make shorthands for common flags
alias ll="ls -lh"
# Save a lot of typing for common commands
alias gs="git status"
alias gc="git commit"
alias v="vim"
# Save you from mistyping
alias sl=ls
# Overwrite existing commands for better defaults
alias mv="mv -i" # -i prompts before overwrite
alias mkdir="mkdir -p" # -p make parent dirs as needed
alias df="df -h" # -h prints human readable format
# Alias can be composed
alias la="ls -A"
alias lla="la -l"
# To ignore an alias run it prepended with \
\ls
# Or disable an alias altogether with unalias
unalias la
# To get an alias definition just call it with alias
alias ll
# Will print ll='ls -lh'
デフォルトでは、エイリアスはシェルセッションを持続させないことに注意してください。
エイリアスを持続させるには、.bashrc
や.zshrc
などのシェル起動ファイルにエイリアスを含める必要があります。
#ドットファイル
多くのプログラムは、ドットファイルと呼ばれる平文のファイルを使って設定されています(ファイル名が .
で始まるため、例えば ~/.vimrc
のように、デフォルトではディレクトリリストの ls に隠れるようになっています)。
シェルは、このようなファイルで構成されたプログラムの一例です。
起動時に、シェルは多くのファイルを読み込んで設定を読み込みます。
シェルによっては、ログインや対話を開始するかどうかに関わらず、プロセス全体が非常に複雑になります。
このテーマに関する優れた資料があります。
bash
の場合、ほとんどのシステムでは .bashrc
または .bash_profile
を編集することができます。
ここには、先ほど説明したエイリアスやPATH環境変数の変更など、起動時に実行したいコマンドを含めることができます。
実際、多くのプログラムは、そのプログラムのバイナリが見つかるように、
export PATH="$PATH:/path/to/program/bin "
のような行をシェル設定ファイルに含めることを求めます。
ドットファイルで設定できるツールの例としては、他にも以下のようなものがあります。
- bash - ~/.bashrc, ~/.bash_profile
- git - ~/.gitconfig
- vim - ~/.vimrc および ~/.vim フォルダ
- ssh - ~/.ssh/config
- tmux - ‾/.tmux.conf
ドットファイルはどのように整理すればよいでしょうか?
独自のフォルダに入れ、バージョン管理を行い、スクリプトを使ってシンボリックリンクで固定するべきです。
これには次のような利点があります。
- 簡単なインストール:新しいマシンにログインした場合、カスタマイズの適用には1分しかかかりません。
- 移植性:あなたのツールはどこでも同じように動作します。
- 同期:どこにいてもdotfilesを更新でき、すべてを同期させることができます。
- 変更の追跡:あなたはおそらく、あなたのプログラミングキャリア全体にわたって
dotfiles
を維持することになるでしょう。
あなたの dotfiles
には何を入れるべきですか?
あなたのツールの設定については、オンラインドキュメントや man
ページを読むことで学ぶことができます。
もう一つの素晴らしい方法は、インターネットで特定のプログラムに関するブログ記事を検索することです。
カスタマイズについて学ぶもう一つの方法は、他の人の dotfiles
を見ることです: Github でたくさんの dotfiles
リポジトリを見つけることができます
最も人気のあるものはこちらです (設定をやみくもにコピーしないことをお勧めします)。
このトピックに関する別の良いリソースはこちらです。
https://github.com/search?o=desc&q=dotfiles&s=stars&type=Repositories
https://github.com/mathiasbynens/dotfiles
https://dotfiles.github.io/
このクラスの講師は全員、GitHub で彼らの dotfiles を公開しています。Anish, Jon, Jose.
https://github.com/anishathalye/dotfiles
https://github.com/jonhoo/configs
https://github.com/jjgo/dotfiles
##移植性
dotfiles
の一般的な問題点は、複数のマシンで作業する際に、例えば異なるオペレーティングシステムやシェルを使用している場合、設定が機能しない可能性があることです。
また、ある設定を特定のマシンにのみ適用したい場合もあります。
これを簡単に行うための方法がいくつかあります。
設定ファイルがそれをサポートしている場合、if-statement
に相当するものを使って、マシン固有のカスタマイズを適用します。
例えば、シェルには次のようなものがあります。
if [[ "$(uname)" == "Linux" ]]; then {do_something}; fi
# Check before using shell-specific features
if [[ "$SHELL" == "zsh" ]]; then {do_something}; fi
# You can also make it machine-specific
if [[ "$(hostname)" == "myServer" ]]; then {do_something}; fi
設定ファイルがそれをサポートしている場合は、include
を利用します。
たとえば、~/.gitconfig
には設定を入れることができます。
[include]
path = ~/.gitconfig_local
そして各マシンでは、~/.gitconfig_local
にマシン固有の設定を入れることができます。
マシン固有の設定を別のリポジトリで管理することもできます。
このアイデアは、さまざまなプログラムで設定を共有したい場合にも便利です。
たとえば、bash
と zsh
の両方で同じエイリアスを共有したい場合は、.aliases
の下にエイリアスを記述し、両方で次のようなブロックを作成します。
# Test if ~/.aliases exists and source it
if [ -f ~/.aliases ]; then
source ~/.aliases
fi
#リモートマシン
プログラマーが日常業務でリモートサーバを使用することは、ますます一般的になってきています。
バックエンド・ソフトウェアをデプロイするためにリモート・サーバーを使用する必要がある場合や、より高い計算能力を持つサーバーが必要な場合、最終的にはSecure Shell (SSH)
を使用することになります。
ここで取り上げるほとんどのツールと同様に、SSH
は高度な設定が可能なので、学んでおく価値があります。
サーバーにログインするには、次のようなコマンドを実行します。
ssh foo@bar.mit.edu
ここでは、bar.mit.edu
というサーバに foo
というユーザで ssh
しようとしています。
サーバは、URL (bar.mit.edu など)
または IP (foobar@192.168.1.42 など)
で指定できます。
後で見てみると、ssh
の設定ファイルを修正すれば、ssh bar
のようにしてアクセスできることがわかります。
##コマンドの実行
ssh foobar@server ls
は、foobar
のホームフォルダで ls
を実行します。
パイプを使って動作するので、ssh foobar@server ls | grep PATTERN
は、ローカルで ls
のリモート出力を grep
し、ls | ssh foobar@server grep PATTERN
は、リモートで ls
のローカル出力を grep
します。
##SSHキー
鍵ベースの認証では、公開鍵暗号方式を利用して、クライアントが秘密の秘密鍵を所有していることを、鍵を明かすことなくサーバーに証明します。
この方法では、毎回パスワードを再入力する必要がありません。
秘密鍵 (多くの場合 ~/.ssh/id_rsa
、最近では ~/.ssh/id_ed25519
) は事実上のパスワードのように扱います。
###鍵の生成
鍵のペアを生成するには、ssh-keygen
を実行します。
ssh-keygen -o -a 100 -t ed25519 -f ~/.ssh/id_ed25519
秘密鍵を手に入れた人が、認証されたサーバにアクセスできないように、パスフレーズを決めておく必要があります。
ssh-agent
や gpg-agent
を使えば、いちいちパスフレーズを入力する必要はありません。
SSH
鍵を使って GitHub
にプッシュする設定をしたことがある人は、おそらくここで説明した手順を実行して有効な鍵ペアを手に入れていることでしょう。
https://help.github.com/articles/connecting-to-github-with-ssh/
パスフレーズがあるかどうかを調べて検証するには、ssh-keygen -y -f /path/to/key
を実行します。
###鍵による認証
ssh
は .ssh/authorized_keys
を調べて、どのクライアントを入れるべきかを決定します。
公開鍵をコピーするには、次のようにします。
cat .ssh/id_ed25519.pub | ssh foobar@remote 'cat >> ~/.ssh/authorized_keys'
よりシンプルな解決策は、ssh-copy-id
が利用できる場合には、それを使って実現できます。
ssh-copy-id -i .ssh/id_ed25519.pub foobar@remote
##SSHでファイルをコピーする
sshでファイルをコピーするには、いろいろな方法があります。
-
ssh+tee
, 最も簡単な方法は、ssh
コマンドの実行とSTDIN
の入力を使ってcat localfile | ssh remote_server tee serverfile
とすることです。tee
はSTDIN
からの出力をファイルに書き込むことを思い出してください。 -
scp
大量のファイルやディレクトリをコピーする際には、パスを簡単に再検索できるsecure copy scp
コマンドが便利です。構文はscp path/to/local_file remote_host:path/to/remote_file
です。 -
rsync
はscp
を改良して、ローカルとリモートで同一のファイルを検出し、再コピーを防止します。また、シンボリックリンクやパーミッションをより細かく制御することができ、--partial
フラグのような特別な機能もあり、以前に中断したコピーから再開することができます。
##ポートフォワーディング
多くの場面で、マシンの特定のポートをリッスンするソフトウェアに遭遇します。
このような場合、ローカルマシンではlocalhost:PORT
または127.0.0.1:PORT
と入力しますが、ネットワーク/インターネットを通じてポートを直接利用できないリモートサーバーではどうすればよいのでしょうか。
これはポートフォワーディングと呼ばれるもので、2つの種類があります。
「ローカルポートフォワーディング」
と「リモートポートフォワーディング」
です(詳しくは写真をご覧ください。写真のクレジットはStackOverflowのこの記事から引用しています)。
https://unix.stackexchange.com/questions/115897/whats-ssh-port-forwarding-and-whats-the-difference-between-ssh-local-and-remot
最も一般的なシナリオは、ローカルポートフォワーディング
で、リモートマシンのサービスがあるポートをリッスンしており、ローカルマシンのポートをリンクしてリモートポートに転送したい場合です。
例えば、ポート8888
をリッスンするリモートサーバでjupyter notebookを実行したとします。
これをローカルポート9999
に転送するには、
ssh -L 9999:localhost:8888 foobar@remote_server
とし、ローカルマシンの locahost:9999
に移動します。
##SSHの設定
これまで、渡すことのできる多くの引数について説明してきました。
魅力的な代替案は、次のようなシェルエイリアスを作ることです。
alias my_server="ssh -i ~/.id_ed25519 --port 2222 -L 9999:localhost:8888 foobar@remote_server
しかし、~/.ssh/config
を使うより良い方法があります。
Host vm
User foobar
HostName 172.16.174.141
Port 2222
IdentityFile ~/.ssh/id_ed25519
LocalForward 9999 localhost:8888
# Configs can also take wildcards
Host *.mit.edu
User foobaz
エイリアスではなく ~/.ssh/config
ファイルを使うことのさらなる利点は、 scp, rsync, mosh
などの他のプログラムでもこのファイルを読み込んで、 設定を対応するフラグに変換できることです。
~/.ssh/config
ファイルはドットファイルとみなすことができ、 一般的には、残りのドットファイルと一緒に入れても問題ないことに注意してください。
しかし、もしこれを公開すると、インターネット上の見知らぬ人に情報を提供することになりかねません。
これは、ある種の攻撃を容易にする可能性がありますので、SSH設定を公開する際には慎重に行ってください。
サーバー側の設定は、通常、/etc/ssh/sshd_config
で指定します。
ここでは、パスワード認証の無効化、ssh ポートの変更、X11 フォワーディングの有効化
などの変更を行うことができます。
コンフィグ設定は、ユーザごとに指定することができます。
###その他
リモートサーバに接続するときによくあるのが、コンピュータのシャットダウンやスリープ、ネットワークの変更などによる接続の切断です。
また、接続に大きなラグがある場合、sshの使用は非常にフラストレーションの溜まるものです。
モバイルシェルであるMoshは、ローミング接続や断続的な接続を可能にし、インテリジェントなローカルエコーを提供するなど、sshを改良しています。
sshfs
は、リモートサーバ上のフォルダをローカルにマウントして、ローカルエディタを使用することができます。
#シェルとフレームワーク
シェルツールとスクリプティングでは、bash
シェルを取り上げました。
bash
は圧倒的にどこにでもあるシェルで、ほとんどのシステムでデフォルトのオプションとして用意されているからです。
しかし、bashが唯一の選択肢というわけではありません。
例えば、zsh
シェルはbash
のスーパーセットで、以下のような便利な機能を備えています。
- よりスマートなグロビング、**
- インライングロブ/ワイルドカード展開
- スペルの修正
- より良いタブ補完/選択
- パス展開 (
cd /u/lo/b
は/usr/local/bin
として展開)
フレームワークもシェルを向上させます。
一般的なフレームワークとしては prezto
や oh-my-zsh
が有名ですが、zsh-syntax-highlighting
や zsh-history-substring-search
など特定の機能に特化した小さなフレームワークもあります。
fish
のようなシェルには、これらのユーザーフレンドリーな機能の多くがデフォルトで含まれています。
これらの機能には次のようなものがあります。
- 右プロンプト
- コマンド構文の強調表示
- ヒストリー部分文字列検索
- manページベースのフラグ補完
- よりスマートなオートコンプリート
- プロンプトのテーマ
これらのフレームワークを使用する際の注意点は、実行するコードが適切に最適化されていなかったり、コード量が多すぎたりすると、シェルの速度が低下する可能性があることです。
頻繁に使用しない機能や、速度よりも重視する機能は、いつでもプロファイリングして無効にすることができます。
#ターミナルエミュレータ
シェルのカスタマイズと同時に、ターミナル・エミュレータの選択とその設定にも時間をかける価値があります。
世の中にはたくさんのターミナルエミュレータがあります(ここに比較表があります https://anarc.at/blog/2018-04-12-terminal-emulators-1/)
ターミナルには何百、何千時間も費やすことになるかもしれませんから、その設定を検討することは有益です。
ターミナルで変更したい点には次のようなものがあります。
- フォントの選択
- 配色
- キーボード ショートカット
- タブ/ペインのサポート
- スクロールバックの設定
- パフォーマンス(Alacrittyやkittyのような新しい端末では、GPUアクセラレーションを提供しているものもあります)
https://github.com/jwilm/alacritty
https://sw.kovidgoyal.net/kitty/
#練習問題
##ジョブの制御
1 . これまで見てきたところでは、ps aux | grep
コマンドを使ってジョブの pid
を取得してから kill
することができますが、もっと良い方法があります。
ターミナルでsleep 10000
のジョブを開始し、Ctrl-Z
でバックグラウンドにし、bg
で実行を継続します。
pgrep
を使ってpid
を見つけ、pkill
を使ってpid
を入力することなくそのジョブを殺すことができます。(ヒント: -af
フラグを使用してください)。
2 . 他のプロセスが完了するまで、あるプロセスを開始したくないとしたら、どのようにすればよいでしょうか?
この演習では、制限プロセスは常に sleep 60 &
とします。そのためには、wait
コマンドを使うのが一つの方法です。
sleep
コマンドを起動して、バックグラウンドプロセスが終了するまでls
を待機させてみてください。
ただし、wait
は子プロセスに対してのみ動作するため、別のbash
セッションで起動すると、この方法は失敗します。
ノートでは説明しなかった機能として、kill
コマンドの終了ステータスは成功した場合は0
、そうでない場合は0
以外の値になります。
kill-0
はシグナルを送信しませんが、プロセスが存在しない場合は0
以外の終了ステータスを与えます。
pid
を受け取り、与えられたプロセスが完了するまで待つpidwait
というbash関数
を書いてください。
CPU
を不必要に浪費しないようにsleep
を使うべきです。
##ターミナルマルチプレクサ
このtmux
チュートリアルに沿って、以下の手順で基本的なカスタマイズを行う方法を学びます。
https://www.hamvocke.com/blog/a-quick-and-easy-guide-to-tmux/
##エイリアス
間違ってcd
と入力してしまったときのために、cd
に解決するエイリアスdc
を作成しておきます。
history | awk '{$1="";print substr($0,2)}' | sort | uniq -c | sort -n | tail -n 10
を実行して、よく使うコマンドのトップ10を取得し、それらのために短いエイリアスを書くことを検討します。
注意:これはBash
で動作します。ZSH
を使用している場合は、単なるhistory
ではなく、history 1
を使用してください。
##ドットファイル
早速ですが、dotfiles
を使ってみましょう。
1 dotfiles
のためのフォルダを作成し、バージョンコントロールを設定します。
2 少なくとも 1 つのプログラム、例えばシェルに、カスタマイズした設定を追加します (最初は、$PS1
を設定してシェルのプロンプトをカスタマイズするような単純なもので構いません)。
3 新しいマシンにドットファイルを素早く(手動ではなく)インストールする方法を設定してください。これは、各ファイルに対して ln -s
を呼び出すシェルスクリプトのような単純なものであってもよいですし、特殊なユーティリティを使用することもできます。
4 新しい仮想マシン上で、インストールスクリプトをテストします。
5 現在のツールの構成をすべて dotfiles
リポジトリに移行します。
6 dotfiles
を GitHub
で公開します。
##リモートマシン
この演習のために、Linux仮想マシンをインストールします(または既存の仮想マシンを使用します)。
仮想マシンに慣れていない方は、こちらのチュートリアルを参考にしてください。
https://hibbard.eu/install-ubuntu-virtual-box/
1 「~/.ssh/」
に移動し、そこに SSH
鍵のペアがあるかどうかを確認します。
ない場合は、ssh-keygen -o -a 100 -t ed25519
で鍵を生成します。パスワードと ssh-agent
の使用をお勧めします(詳細はこちら https://www.ssh.com/ssh/agent )
2 .ssh/config
を編集し、以下のようなエントリを作成します。
Host vm
User username_goes_here
HostName ip_goes_here
IdentityFile ~/.ssh/id_ed25519
LocalForward 9999 localhost:8888
1 ssh-copy-id vm
を使用して、ssh
鍵をサーバにコピーします。
2 python -m http.server 8888
を実行して、VM
内で Web
サーバを起動します。お使いのマシンで http://localhost:9999
に移動して、VM
ウェブサーバにアクセスします。
3 sudo vim /etc/ssh/sshd_config
を実行して SSH
サーバーの設定を編集し、PasswordAuthentication
の値を編集してパスワード認証を無効にします。PermitRootLogin
の値を編集して、ルートログインを無効にします。sudo service sshd restart
で ssh
サービスを再起動します。再度ログインしてみてください。
4 (Challenge) VM
に mosh
をインストールし、接続を確立します。その後、サーバ/VMのネットワークアダプタを切断します。mosh
はそこからきちんと復旧できますか?
5 (課題) ssh
で -N と -f
フラグが何をするかを調べて、バックグラウンドのポートフォワーディングを実現するためのコマンドを考えてみてください。