iTranslated by AI
Shell Trick: Saving and Executing Partially Entered Commands Later
Have you ever realized while typing a long, tedious command in the shell that you should have executed another command first? This probably happens quite often, especially for those of you who love one-liner scripts. In such situations, do you reluctantly delete the text you were typing, run the other command, and then retype the original one? Or do you cut the string and paste it later?
Here is a small trick to temporarily save the command you are typing and execute it later. Where do you save it? In your shell history. Specifically, the method is: "move to the beginning of the command, type '#', and press Enter; then, after finishing the other task, find it in your history, remove the '#', and execute it." Here is an example:
- You type as far as
awk '{<long one-liner>}' <input.data > output.dataand realize, "Wait, I haven't generated input.data yet!" - Move to the beginning of the line, type "#", and press Enter. Since it's treated as a comment, nothing is executed, but it remains in your history (with the "#").
- Run the command to generate input.data. For example,
make input.data. - Scroll through your history using the "↑" key or similar. You will find
#awk '{<long one-liner>}' <input.data > output.data. - Move to the beginning of the line, delete the "#", and press Enter.
- It succeeds because
input.datanow exists.
It's not like you're using a hidden feature of the shell or terminal; it's a simple trick once you know it. However, since quite a few people around me didn't know it, I decided to share it here. That's all.
Discussion
こんなに簡単な方法があったとは!
Ctrl+u, Ctrl+y でも同様のことがもっと簡単にできる気がするのですが、こちらの方法を使うメリットは何でしょうか?
2回以上Ctrl+uをすると、n-1回目の内容が消えませんか
あいやさんがおっしゃるとおり、同様のことを複数回やったときに全て履歴に残せるのがメリットです。C-u C-yだと最新のものしか残せないです。
なるほど、確かに仰る通りですね。2回以上Ctrl+uしたときに「あ〜さっき切り取ったやつ復元したい…」となったときの気持ちを思い出しました。
Zsh だと Ctrl-y → ESC-y → ESC-y ... で戻れるみたいですね。
Ctrl-u を yank できるのを初めて知りました。 🙏
コレよくやるけど、前側のコマンドを追加修正して実行してを何度か繰り返してるうちに、# の存在を忘れたまま # の後ろのコマンド部分を直し始めてしまい、当然#の後ろを直しても何も変わらんのでうまく動作しないと悩むフェーズに入りがち…。
ためになる tips を共有してくださりありがとうございます!
bash を想定されている記事かと思いますが、zsh では少し挙動が異なるので共有します。
zsh ではデフォルトで 対話モードでは
#がコメントになりません!そのため、何も設定していない場合:
のようなエラーになります。
bash と同じく対話モードでも
#以降をコメントにしたい場合は、.zshrcに次の 1 行を追加する必要があります。エラーになっても履歴を残すという目的は達成しているのでいいような。
へえ~、そんなオプションが…!
僕はそれを知らなかったので、
:コマンドを使っていました 🙋♂️:がコマンドとして定義されていること初めて知りました…!!こちらだとPOSIX準拠のシェルで動作が統一されていそうなので、本記事のテーマの最適解な気がしてきました(展開の副作用は反映されるようですが)
zshならESC q (M-q)のpush-lineを使ってほしい。
同じことechoでやってましたが使えるなら#のほうがベターそうですね。参考になりました
便利なテクをありがとうございます。
カーソルを0文字目に戻す操作を、素の状態で試してみたら
bashでは
Ctrl + ←、Fn + ←、Alt + ←で行けました。zshだと
Ctrl + ←、Fn + ←だけ行けました。Fnのこんな機能は知りませんでした。
ctrl+a ではだめですか?
Ctrl + aでどっちのシェルも行けました。左手だけで操作できて便利なのですね。
あと訂正で、
Ctrl + aと同じ挙動はCtrl + ←だけでほかは半角スペース区切りの先頭でした。
ですよね。ちなみにctrl+eで行末です。
ctrl+e ctrl+u と連続で打つと行が全て消えて便利です。
今までは、ctrl + cで一度中断した後に、入力途中のコマンドをコピー&貼り付けしてから入力し直していたので、
とても参考になりました。
先頭に#を入れる or 先頭に#ある場合は除く、動作をキーバインドで設定すると良さそうと思ったので、zshの例ですが、zsh widgetを考えてみました。