モチベーション
最近、ペラペラと「Efficient Linux コマンドライン」(参考[1])という書籍を読んでいました。その中で自分は普段使いできていないが、便利そうだと感じたコマンドを備忘録的にアウトプットしたいと思い記事を書きました。
- コマンド再実行系
- コマンド補完系
- テキスト入出力系
- その他
として分類したので気になった項目をご覧いただければと思います。
コマンド再実行系
- historyを参照した再実行
historyの位置番号を元にコマンドを再実行する方法です。
### texの文字列が含まれるコマンドの履歴を検索する
$ history | grep tex
1234 emacs workdir/sample/main.tex
### コマンド履歴の中の1234の位置に存在するコマンドを再実行する
### 以下を実行するとemacs workdir/sample/main.texが再実行される
$ !1234
私は上記のようにhistoryコマンドで履歴を表示/確認はするものの、毎回 Ctrl + R でコマンドの実行履歴を検索して打ち直す癖があったので今後は時短のために、こちらを利用してみます。
コマンド補完系
- 自前で定義した関数にtab補完を設定する
以下のように記述したdummy関数の末尾にcompleteから始まる補完の定義を記載し、bashrcに追記してみます。
### テスト用の関数 よく使うコマンドなどをbashrcに記述すると便利
dummy () {
### dummyコマンドの第一引数で場合分け
case "$1" in
hoge)
echo "hoge"
;;
fuga)
echo "fuga"
;;
*)
echo "Unknown option '$1'"
return 1
;;
esac
}
### tab補完を定義する
complete -W "hoge fuga" dummy
dummy関数を呼び出してtab補完を実行しようとすると以下のように候補が出力されます。
$ dummy [tab]
fuga hoge # fugaとhogeがsuggestされる
上記のdummy関数を例に、頻繁に実行するshellscriptやコマンドなどを関数としてbashrcにまとめておき、そこに補完を記述してあげることで効率的にコマンド実行ができます。
なお、これはあくまでbashに限った話でcompleteコマンドは使用するshellによってかなり挙動が変わるのでご注意ください。zshを利用する場合はcompdefによる補完ファイルの作成などを行う必要があります。この辺りの情報が参考になるかと思います。 (参考[2])
- AUTO_PUSHDを使ってディレクトリスタックを活用する(zsh限定)
複数のディレクトリをcdコマンドで移動しまくるのは非常に面倒です。zsh限定にはなってしまいますが、setopt auto_pushdを.zshrcに追記することで、ディレクトリ移動時に元々自身がいたディレクトリがstackに積まれていきます。挙動は以下の通りです。
$ pwd
/home/ro644/tmp/ubuntu-sandbox/home # カレントディレクトリ表示
$ cd - [tab]
0 -- ~
1 -- ~/tmp
2 -- ~/tmp/ubuntu-sandbox
3 -- ~/tmp/ubuntu-sandbox/home
4 -- ~/tmp/ubuntu-sandbox/home/ubuntu
5 -- /lib
あとはtab補完なりで、自身がいたディレクトリを選択し移動することができます。書籍中ではpushd / popd / cd – を紹介していたのですが個人的に上記が更に便利かと思い、紹介させていただきました。
テキスト入出力系
- 特定の文字列を含んだファイルのファイル名のみをリストアップ (grep -l)
毎回忘れるコマンドその1。
便利かつやっていること自体はとても単純なコマンドなのですが、利用する頻度が少なく記憶に残らないため記載しました。ログローテートするファイル群に対してキーワード検索したい時などに利用します。
$ echo "apple" > test1.log
$ echo "banana" > test2.log
$ echo "orange" > test3.log
### 文字列appleが含まれるtest1.logが出力される
$ grep -l "apple" *.log
test1.log
- SSHを使ったコマンド実行 文字列をローカル/リモートで出力する
毎回忘れるコマンドその2。
クオートの有無によってローカル/リモートのどちらにファイルが生成されるかが変わります。これは知らなかったのですが、パイプでsshサーバにコマンドを飛ばしてそれを実行させることも可能です。
### ListFile.outはローカルマシン上に作成される (ex.1)
$ ssh 192.168.XX.XX ls > ListFile.out
### ListFile.outはリモートマシン上に作成される (ex.2)
$ ssh 192.168.XX.XX "ls > ListFile.out"
### コマンドをsshにパイプで渡してリモート上で実行させる (ex.3 結果はex.2と同じ)
$ echo "ls > ListFile.out" | ssh 192.168.XX.XX
上記 ex.3 実行時にmotdなどが出力されて邪魔な場合は末尾に”bash”を引数として付与することで余計なメッセージの出力を抑えられる。
- ブラッシュワンライナー (複数コマンドを1行にまとめて実行)
HPCクラスタのシステム管理者は重宝しそうなコマンド。
echo {..} を使って、連続した数字を自動で入力させ、その結果をパイプに渡して整形する方法。以下は計算ノード(compute01 ~ 10)を再起動するコマンドを出力してくれるサンプルコマンド。(※ 例はあくまで出力するだけにとどめている)
### "shutdown -r now"の部分は他のコマンドに入れかえて利用可
$ echo "ssh "compute{10..01}" shutdown -r now" | sed 's/ ssh/\nssh/g'
ssh compute10 shutdown -r now
ssh compute09 shutdown -r now
ssh compute08 shutdown -r now
ssh compute07 shutdown -r now
ssh compute06 shutdown -r now
ssh compute05 shutdown -r now
ssh compute04 shutdown -r now
ssh compute03 shutdown -r now
ssh compute02 shutdown -r now
ssh compute01 shutdown -r now
この項については今後も自身が見つけた便利なブラッシュワンライナーを見つけ次第適宜加筆していく予定です。
その他
- 条件付きコマンドリスト ( && / || )
コマンドの終了コードに基づいて、連続するコマンドを実行させたりさせなかったりする。書籍内ではファイルバックアップの作成と削除などを利用例として挙げています。
### cd dirが成功した場合にdir内にnew.txtを生成する
$ cd dir && touch new.txt
### cd dirが失敗した場合のみmkdir dirを実行する
$ cd dir || mkdir dir
- コマンド埋め込みの中に更にコマンドを埋め込む
コマンドを埋め込む際に私はバッククォートを埋め込んでいたが、更にその中にコマンドを入れ込みたい時などは以下の例のように $() でコマンドを括ったほうが便利かと思います。
### コマンドが三重で入れ子になっている例
$ echo Today is $(echo $(date +%A) | tr a-z A-Z)!
Today is TUESDAY!
参考にさせていただいた情報
[1] Efficient Linuxコマンドライン ―開発と自分に磨きをかけるLinuxのテクノロジー | Daniel J. Barrett, 大嶋 真一, 原 隆文 |本 | 通販 | Amazon
[2] Zsh: 自作コマンドで補完できるようにする
以上
コメントを残す