人のオペレーションを見てるとそれぞれクセがあっておもしろいですよね!
というわけで自分がよく使うbashの便利機能をまとめてみました。
1つ前の作業ディレクトリに戻る
cd -で戻れます。
[mikeda@test01 tmp]$ cd [mikeda@test01 ~]$ cd - [mikeda@test01 tmp]$
pushd、popdを使えば2つ前でも3つ前でも戻れるのですが、めんどうなので基本コレだけ使ってます。
コマンドラインを移動する
この状態から
Ctrl+aを入力するとプロンプトが先頭に移動します。
Ctrl+eを入力すると末尾に移動です。
Ctrl+wを入力すると直前のワードを削除できます。
Ctrl+cで入力をキャンセルして次の行に移ります。
自分がよく使うのはこの4つです。
ヒストリをうまく使う
ヒストリ検索
Ctrl+rを入力するとヒストリ検索モードになります
[mikeda@test01 ~]$ (reverse-i-search)`':
テキストを入力するとヒストリ中でそれを含むものが出てきます。
[mikeda@test01 ~]$ (reverse-i-search)`cat': cat /etc/hosts
Ctrl+rをさらに入力すれば次々とヒストリをさかのぼっていけます。
そのままEnterで実行してもよし、ちょっといじって実行してもよし、です。
また「!文字列」でその文字列含む直前のコマンドを実行できます。
[mikeda@test01 ~]$ !cat cat /etc/hosts 127.0.0.1 test01 localhost.localdomain localhost ::1 localhost6.localdomain6 localhost6 192.168.1.10 puppet-m.mikeda.jp
ヒストリ番号で実行
「!ヒストリ番号」でそのコマンドを実行できます
[mikeda@test01 ~]$ history |grep cat 973 cat /etc/hosts 974 cat /etc/passwd [mikeda@test01 ~]$ !974 cat /etc/hosts 127.0.0.1 test01 localhost.localdomain localhost ::1 localhost6.localdomain6 localhost6 192.168.1.10 puppet-m.mikeda.jp
直前のコマンドの最後の引数を使う
「!$」で参照できます。
[mikeda@test01 ~]$ file /tmp/test.log /tmp/test.log: ASCII text [mikeda@test01 ~]$ cat !$ cat /tmp/test.log test
- 中身をcatで確認してからviで編集
- ファイルサイズを確認してから圧縮、解凍
など、1つのファイルに連続してオペレーションを行う機会は多いので、ものすごく便利です。
直前のコマンドの全てを使う
「!!」で参照できます。「!$」に比べると使用頻度は落ちますが、
パーミッションエラーならsudoつきで再実行、
[mikeda@test01 ~]$ cat /etc/sudoers cat: /etc/sudoers: 許可がありません [mikeda@test01 ~]$ sudo !! sudo cat /etc/sudoers ## Sudoers allows particular users to run various commands as ## the root user, without needing the root password. ...
直前のコマンドをwatchで繰り返し実行、
[mikeda@test01 ~]$ ls -l /tmp/test.log -rw-rw-r-- 1 mikeda mikeda 5 3月 11 13:58 /tmp/test.log [mikeda@test01 ~]$ watch !!
などでたまに使います。
ブレース展開
「{}」で囲んだ文字列をbashがいい感じに展開してくれる機能です。
[mikeda@test01 ~]$ echo {1..5} 1 2 3 4 5 [mikeda@test01 ~]$ echo /usr/{bin,src} /usr/bin /usr/src
階層的なディレクトリを一気に作るとか
[mikeda@test01 tmp]$ mkdir -p work{1..3}/{bin,lib,conf} [mikeda@test01 tmp]$ tree . |-- work1 | |-- bin | |-- conf | `-- lib |-- work2 | |-- bin | |-- conf | `-- lib `-- work3 |-- bin |-- conf `-- lib
バックアップやアーカイブの作成コマンドを簡略化したりとか、
[mikeda@test01 tmp]$ cp -a work1{,.bak} [mikeda@test01 tmp]$ tar czf work1{.tgz,} [mikeda@test01 tmp]$ ls work1 work1.bak work1.tgz work2 work3
たまに便利です。
でも一番使うのはfor文の引数ですね。
for文、while文を使う
コマンドラインでもよく使います。
for文はワイルドカードで複数ファイルに一括操作が1つの使い方。
for i in *.log;do mv $i /backup/;done
例がイマイチですね><
連続する数値を扱う場合はこういう例が多いかもですが
for ((i=0;$i<10;i++));do echo $i;done for i in `seq 10`;do echo $i;done
自分はブレース展開で書いちゃうのがPerlっぽくて好きです。
for i in {1..10};do echo $i;done
追加で、指定ホストに次々SSHログインしていく例
for i in 192.168.1.{1..3} test-{web,db};do ssh $i;done
whileはreadと組み合わせて使うのがほとんどです。
[mikeda@test03 ~]$ cat hosts.list 192.168.1.51 192.168.1.52 [mikeda@test03 ~]$ while read l;do echo "## $l";ssh -n $l "hostname";done < hosts.list ## 192.168.1.51 test01 ## 192.168.1.52 test02
readの使い方はいろいろ工夫の余地があります。
# 複数の変数で受け取る。区切り文字は空白文字で、あふれると最後の変数にまとめられる。 egrep -v '^($|#)' /etc/hosts | while read ip hosts;do echo $ip;done # 区切り文字はIFS変数で変更可能 while IFS=: read user pass uid gid others;do echo $user $uid;done < /etc/passwd
無限ループはこんな感じで
[mikeda@test01 ~]$ while :;do date;sleep 3;done 2012年 3月 11日 日曜日 15:16:07 JST 2012年 3月 11日 日曜日 15:16:10 JST 2012年 3月 11日 日曜日 15:16:13 JST
while trueでもOKですよ!
ついでに、↑のIFSの使い方もそうですが、
一時的に変数を変更したい場合は単独で代入文を書くのではなく、
[mikeda@test03 ~]$ LANG=C [mikeda@test03 ~]$ date Sun Mar 11 15:01:07 JST 2012
コマンドの前に書きましょう。
[mikeda@test01 ~]$ LANG=C date Sun Mar 11 14:55:49 JST 2012 [mikeda@test01 ~]$ date 2012年 3月 11日 日曜日 14:55:50 JST
へんな副作用が防げます。
終わりに
みんなそれぞれいろんなテクニックを持ってると思うので、
「こんな便利な機能があるよ!」というのがぜひあれば教えて下さい!