シェルで長ったらしいコマンドを入力している途中に「先に別のコマンドを実行しておくべきだった」と気付いたことはないでしょうか。とくにワンライナースクリプトLOVEなみなさんは、こういうことがよく発生するのではないでしょうか。こういうときに泣く泣く入力中の文字列を消してから別のコマンドを実行して、いったん削除したコマンドを打ち直しているでしょうか。それとも、文字列をカットしてから後から貼り付けしているでしょうか。
こういうときに入力中だったコマンドを一時保存して後から実行する小技を紹介します。どこに一時保存するかというと、それはシェルの履歴です。具体的には「入力中だったコマンドの先頭に移動して「#」を入力してからenterを押す、他のことをした後に履歴をたどって"#"を消して実行」というものです。以下に例を示します。
awk '{<長大なワンライナー>}' <input.data > output.data まで入力したところで「しまった、input.dataをまだ生成していない!」と気づくmake input.dataなど。#awk '{<長大なワンライナー>}' <input.data > output.dataが見つかる。input.dataがあるので無事成功。別にシェルやらターミナルやらの隠された機能を使うわけではない、知ってしまえば大したことないネタですが、身の回りに知らない人がけっこういたので、ここでも共有しました。おわり。
Rook(メンテナ)/Ceph/K8s/TopoLVM(メンテナ)書籍amazon.co.jp/dp/477419607Xyoutubeyoutube.com/channel/UCgrUyRFiHhV607Orhriau6w
バッジを受け取った著者にはZennから現金やAmazonギフトカードが還元されます。
コレよくやるけど、前側のコマンドを追加修正して実行してを何度か繰り返してるうちに、# の存在を忘れたまま # の後ろのコマンド部分を直し始めてしまい、当然#の後ろを直しても何も変わらんのでうまく動作しないと悩むフェーズに入りがち…。
ためになる tips を共有してくださりありがとうございます!
bash を想定されている記事かと思いますが、zsh では少し挙動が異なるので共有します。
zsh ではデフォルトで対話モードでは# がコメントになりません!
そのため、何も設定していない場合:
$ # echo hellozsh: command not found: #のようなエラーになります。
bash と同じく対話モードでも# 以降をコメントにしたい場合は、.zshrc に次の 1 行を追加する必要があります。
setopt INTERACTIVE_COMMENTSエラーになっても履歴を残すという目的は達成しているのでいいような。
へえ~、そんなオプションが…!
僕はそれを知らなかったので、:コマンドを使っていました 🙋♂️
$# cp ~/Repository/vket-boilerplate-nuxt/develop/{.editorconfig,.gitattributes,.lintstagedrc.json,.prettierrc} .zsh: command not found: #$:cp ~/Repository/vket-boilerplate-nuxt/develop/{.editorconfig,.gitattributes,.lintstagedrc.json,.prettierrc}.(no output): がコマンドとして定義されていること初めて知りました…!!
こちらだとPOSIX準拠のシェルで動作が統一されていそうなので、本記事のテーマの最適解な気がしてきました(展開の副作用は反映されるようですが)
https://pubs.opengroup.org/onlinepubs/009695399/utilities/colon.html
便利なテクをありがとうございます。
カーソルを0文字目に戻す操作を、素の状態で試してみたら
bashではCtrl + ←、Fn + ←、Alt + ← で行けました。
zshだとCtrl + ←、Fn + ← だけ行けました。
Fnのこんな機能は知りませんでした。
今までは、ctrl + cで一度中断した後に、入力途中のコマンドをコピー&貼り付けしてから入力し直していたので、
とても参考になりました。
先頭に#を入れる or 先頭に#ある場合は除く、動作をキーバインドで設定すると良さそうと思ったので、zshの例ですが、zsh widgetを考えてみました。
_insert_comment(){if[[$BUFFER=~ ^[[:space:]]*# ]]; then# 既にコメントアウトされている場合は解除BUFFER=${BUFFER#"${BUFFER%%[![:space:]]*}"}# 前方の空白を削除BUFFER=${BUFFER#\#}# #を削除BUFFER=${BUFFER#[[:space:]]}# #の後の空白を削除else# コメントアウトされていない場合は追加BUFFER="#$BUFFER"fi zle redisplay}zle-N _insert_commentbindkey'^Q' _insert_comment# ctrl + qで先頭に#追加 or 削除Rook(メンテナ)/Ceph/K8s/TopoLVM(メンテナ)書籍amazon.co.jp/dp/477419607Xyoutubeyoutube.com/channel/UCgrUyRFiHhV607Orhriau6w