コマンドライン上のファイル操作で事故らないために


カレントディレクトリにある全ての画像ファイルを親ディレクトリに移動する時に事件は起こりました。

  • やらかしたコマンド
$ sudo mv /* ../
  • やりたかったコマンド
$ sudo mv ./* ../

結果はご想像にお任せしますが、まさかこんなことになるとは思いませんでした。
唯一の救いは、この事件はサーバ移行中の作業で、やらかしたのが移行先のサーバの方だっということです。
そんなこともあり、最近ではmvコマンドを打つ時はかなり慎重にっています。もちろんrmコマンドなども。

mvする対象が確認不足が原因だったのではないか?

問題点

  • 操作する対象がカレントディレクトリ以外を指定してしまった
  • 操作する対象が可視化されていなかった

例えば

$ sudo mv /bin /root /sbin /usr /var ../

などと表示されていたら絶対にEnterを押さないですよね?

改善策

  • 操作する対象はカレントディレクトリを指定する
  • 操作する対象のファイルやディレクトリを全てコマンドラインに表示する

例えば、
カレントディレクトリにあるpictreu1.png ~ picture10.pngの10ファイルを移動したいときは

$ mv /*.png ../

ではなく

$ mv picture1.png picture2.png picture3.png picture4.png picture5.png picture6.png picture7.png picture8.png picture9.png picture10.png ../

と表示されるようにする。

pecoで操作対象を選択する

pecoについてはこちらを参考にしてください。

aliasの設定

function peco-files() {
    local files="$(ls -a | peco | tr '\n' ' ')"
    if [ -n "$LBUFFER" ]; then
        BUFFER="$LBUFFER$files"
    fi
    CURSOR=$#BUFFER
}
zle -N peco-files
# ctrl + fで起動
bindkey '^f' peco-files

アクションの定義とキーマップ

~/.peco/.config.json
{
    "Action": {
        "selectAllAndFinish": [
            "peco.SelectAll",
            "peco.Finish"
        ]
    },
    "Keymap": {
        "C-a": "selectAllAndFinish"
    }
}

これで mvを入力した後に、pecoで選択すればコマンドライン上に全てのファイルが表示されます。そして移動先のフォルダを指定して実行します。
もちろんmv以外のコマンド使えます。

謝辞

最後まで読んでいただき、まことにありがとうございます。