シェル、だいじですよね
シェル、書いてますか!?僕はほぼ毎日書いてます!
今や職業プログラマーでも、DevOpsの名の下にサーバ運用をしたり、
開発だけする身であっても、DockerやGitをフル活用していくのが当たり前になってきていますよね!
そこで覚えたいコマンドの数々なんですが、GitだとかDockerだとか、どうにも面倒なコマンド多いですよね
そこで今回は、できるだけ複雑なことをしないでちょっとの工夫で幸せになれる、僕がよく使うコマンドをいくつかご紹介したいと思います!
覚えることはたった二つです!
- alias
- サブシェル
シェルばりばりだぜー!って人でもないと、意外と使ってる人が少ないこれらの機能について紹介してみたいと思います!これで今日からちょっぴり幸せ!
これがやりたいだけなのに・・・
例えばGitあるある
- いらないファイルを
rm
で沢山消したら、大量のdeleted ~~
が発生!しかももうファイル消しちゃってるからBashだと補完も効かない・・・ - 今日は沢山ブランチ切って沢山PRして沢山マージされたぞ!…あれ?ローカルに大量の不要なブランチが…まとめて消したいなぁ。
-
git stats
あっ!git statsu
あれっgit sttaus
…あぁもうっ!
例えばDockerあるある
- 今起動中のDockerコンテナにログインするよ!えーっとまず
docker ps
でコンテナのID確認して、コピペして(めんどくさいなぁ、なんでマウス使ってるんだろ…)、docker exec
に貼り付けてって手順だったな、よしよし、じゃあ早速docker ps
…あぁsudo
つけてなかった!もうっ! - 最新のコンテナのログを見たいなぁ、えーっと
docker ps
して(以下同文
例えばJava/Mavenあるある
- 調子悪いから一旦綺麗にしてからインストールしよう、テストはスキップで。えーとコマンドなんだっけ、あ、あったあった。
mvn -U clean install -Dmaven.test.skip=true
って長いよ!めんどくさいよ!わざわざ「コマンド.txt」にメモってあるの開いていつもそこからコピペしてるよ!
alias(エイリアス)使いましょう
エイリアスとは、簡単に言えばコマンドにニックネームを付けるみたいなイメージです。
例えば上記の git status
を何度も打ち間違えてしまう慌てんぼうさんには、以下のようなエイリアスがオススメです。
alias gs="git status"
これを、お手元の~/.bashrc
に書いておくだけで、次にシェルを起動したときからは、git status
をgs
と打つだけで実行できるようになります。
Docker系のコマンドのように、必ずsudo
をつけて実行しなければならないようなものも、毎度毎度書くのが面倒なら
alias docker="sudo docker"
等としておけば、docker
と打つたびに毎度sudoを自動でつけてくれます(でもコマンドミスやセキュリティには注意!)
エイリアスは、コマンドの内容を前方一致で好きなだけかけるため1、例えば上のmavenの例も・・・
# 例えば maven install test skip を略して mits にしてみるとか
alias mits="mvn -U clean install -Dmaven.test.skip=true"
これでこの長くてうんざりするコマンドも、次からmits
で一発です。
「コマンド.txt」は窓から放り投げてやりましょう。
サブシェルを使いましょう
さてさて、あるあるの例でご紹介した中の、残りのケースはこのサブシェルで解決できます。
サブシェルとは、シェルの中でもう一つ子シェルを立ち上げて、そこでコマンドを実行した結果を、呼び出し元の親に返す代物です。
サブシェルは$()
のカッコの中や、``
(バッククォート記号)で囲った中に、いつもどおりのシェルコマンドを入れることで実現できます。``
の方がお手軽そうに見えますが、$()
であれば、サブシェルの中にサブシェルをネスト(入れ子)したりできるので、覚えておくといいですよ!
…と、ちょっと説明だと難しいですね。実例で紹介した方が早そうなので、早速先ほどの問題を解決してみましょう。
rmで消したファイルを、git上からもちゃんとdeleteしたい。
通常はgit rm ~~
でファイルを消せば問題ないのですが、ついうっかり普通にrm -rf ~~
とかで消してしまうこと、ありますよね?僕はよくあります。というか毎回やるといっても過言ではないです
これらをコミットしたいとき、一々git status
で出てきた結果をコピペしたり頑張って手打ちしたりしてgit rm
に渡して一つずつ消す・・・面倒なことこの上ありません。そこで、サブシェル使って一発解決です!
git rm $(git ls-files -d)
これで、「git管理されてるはずなんだけど、ローカルのファイルシステム上にはもう存在してないファイル」をまとめて消せます!
ちょっと解説
簡単に言うと、git ls-files -d
という、git管理されたコマンドを列挙するだけのコマンド(-dをつけると削除されたファイルだけを一覧する)を実行し、その結果をgit rm
に渡してるだけなんです。このコマンドは、例えば実際にはこんな感じに展開されて実行されます。
git rm ./a/hoge.txt ./a/fuga.txt ./a/piyo.txt ./b/foo.txt ./b/bar.txt ./b/baz.txt ./b/qux.txt
上の例では沢山のファイル名が列挙されていますが、つまりこれがgit ls-files -d
の実行結果であるというだけの話なので、あまり難しく考える必要はありません。
じゃあ同じように別のコマンドも解決してみましょう。
沢山増えちゃったブランチを一気に綺麗にしたい!
これも簡単です、以下のコマンドでOK!
git branch -D $(git branch)
git branch
の結果をそのままgit branch -D
に渡してしまうという荒業です!
これで今自分がcheckoutしているブランチ以外の全てのローカルブランチ(リモートブランチには影響がないところがポイント!)を消すことができます。ちょっと怖いなって方は-D
を-d
に変えれば、まだ派生元にマージされていないようなブランチはエラーが出て消さないでおいてくれるので、最初はそっちで試してみるのもいいかもしれません。
でも一応やる前には、ちゃんととっておきたいブランチが他に無いか確認してからにしましょうね!
起動中の(最新の)Dockerコンテナにログインしたい
普通にやると、例のとおり、docker ps
で表示されるコンテナのIDをコピーなりしておいて、docker exec -it {ID} /bin/bash
のような感じで、IDを貼り付けたりしますね。でもこれは以下のコマンドでOKです。
docker exec -it $(docker ps -lq) /bin/bash
もうお分かりかと思いますが、docker ps -lq
がサブシェルですね!このコマンドは「最後に作成されたコンテナのIDのみを出力する」というものになります。つまりそれをいつもどおり docker exec -it {ID} /bin/bash
に渡してあげているだけです。こうすると、このコマンドだけ覚えておけば、もう一々docker ps
を打って、目で見てコピペしなくて良くなります。
でも一つだけ注意
勘のいい方なら、ここで「さっきのaliasと組み合わせればもっと簡単なんじゃ?」と思うかもしれませんが
実はサブシェルとエイリアスはあまり相性がよくありません
サブシェルは多くの場合、.bashrc
等、そのシェルで一度だけ読み込まれるようなファイルに記述するので、コマンドを打つたびには再実行されません。そのため、サブシェルの中の結果は、いつも最初に定義した(読み込んだ)時の結果だけになってしまい、コンテナIDなどの動的に変わる値を使うのはちょっと難しいです。そういう場合はfunction
を定義しておくと、呼ばれる度に新たに実行されるためこの問題を解決することができます(詳しくはシェルのfunctionでぐぐってみてください!)。
まとめ
サブシェルとエイリアス、べんりです!!
できるだけ初心者の方にも分かりやすいように書いたつもりでしたが、最後の方はちょっと難しかったかな・・・
ここに書いてあるようなコマンドは一例ですが、こんな風にちょっと工夫するだけで、面倒だった処理がいきなり簡単になって快適になったりするところがシェルの大きな魅力だと思っています!皆もシェル好きになろうよ!怖くないよ!!
…あ、うそ、たまにはちょっと怖いかもw
間違いや説明不足などありましたら、お気軽にコメントください
では皆さん良いシェルライフを
-
zshとかだと、グローバルエイリアスといって、コマンドの途中部分だけをaliasにすることなどができたりします。例えば最後の一番覚えにくそうな
-Dmaven.test.skip=true
の部分だけをエイリアスにしてあげたりすることができるようになり、汎用性が高まります。興味のある方はzshを是非使ってみてくださいね!補完も優秀でとってもオススメです! ↩