`rm` でゴミ箱に移動する

`rm` でゴミ箱に移動する

ファイルを削除する代わりに、それらを特別な「ゴミ箱」の場所に移動する Linux スクリプト/アプリケーションはありますか? これを代替手段として使用したいですrm(後者をエイリアス化することもできますが、それには長所と短所があります)。

「ゴミ箱」とは、特別なフォルダを意味します。1つのフォルダはmv "$@" ~/.trash最初のステップですが、理想的には、同じ名前の複数のファイルをゴミ箱に入れるときに、古いゴミ箱のファイルを上書きせずに、復元する簡単なコマンド(一種の「元に戻す」)でファイルを元の場所に戻すことができます。さらに、再起動時にゴミ箱が自動的に空になる(または無限に大きくなるのを防ぐ同様のメカニズム)と便利です。

この問題に対する部分的な解決策は存在しますが、特に「復元」アクションは簡単ではありません。グラフィカル シェルのゴミ箱システムに依存しない既存の解決策はありますか?

(余談ですが、頻繁なバックアップや VCS を使用するよりも、このアプローチが正当化されるかどうかについては、議論が尽きることがありません。これらの議論には一理ありますが、私のリクエストにはまだニッチな部分があると思います。)

答え1

そこにはゴミの仕様(案)freedesktop.org で公開されています。これは、デスクトップ環境で通常実装されているもののようです。

コマンドライン実装はゴミ箱-cli詳しく調べていないのですが、必要な機能を提供しているようです。そうでない場合は、これがどの程度部分的な解決策にすぎないのか教えてください。

任意のプログラムを代替/エイリアスとして使用することに関してはrm、そうしないほうがよい理由がいくつかあります。私にとって最も重要なのは次の点です。

  • プログラムは のすべてのrmオプションを理解して処理し、それに応じて動作する必要がある。
  • 「新しいrm」のセマンティクスに慣れてしまい、他の人のシステムで作業しているときに致命的な結果をもたらすコマンドを実行するリスクがあります。

答え2

前の回答では、コマンドtrash-cliとについて言及していますrmtrash。どちらもUbuntu 18.04ではデフォルトで見つかりませんが、コマンドgioです。コマンドgio help trash出力:

Usage:
  gio trash [OPTION…] [LOCATION...]

Move files or directories to the trash.

Options:
  -f, --force     Ignore nonexistent files, never prompt
  --empty         Empty the trash

私はテストしましたgio trash FILENAMEコマンドラインで、ファイルブラウザでファイルを選択してDELボタンをクリックしたときと同じように動作します。ファイルはデスクトップのゴミ箱フォルダに移動さ​​れます。(オプションを使用しなかったにもかかわらず、コマンドは確認を求めません-f。)

rmこの方法でファイルを削除すると元に戻すことができますが、安全のために再定義して削除ごとに確認するよりも便利ですrm -i。ただし、削除すべきでないものを誤って確認してしまった場合は、運が悪くなります。

alias tt='gio trash'エイリアス定義ファイルにtt「to trash」の略語を追加しました。

2018-06-27 編集時に追加:サーバー マシンには、ゴミ箱ディレクトリに相当するものはありません。私は、その目的を果たす次の Bash スクリプトを作成しました。デスクトップ マシンでは を使用しgio trash、他のマシンでは、パラメータとして指定されたファイルを、作成したゴミ箱ディレクトリに移動します。このスクリプトは動作がテスト済みで、私自身も常に使用しています。スクリプトは2024-04-12に更新されました。

#!/bin/bash

# move_to_trash
#
# Teemu Leisti 2024-04-12
#
# USAGE:
#
#   Move the file(s) given as argument(s) to the trash directory, if they are
#   not already there.
#
# RATIONALE:
#
#   The script is intended as a command-line equivalent of deleting a file or
#   directory from a graphical file manager. On hosts that implement the
#   FreeDesktop.org specification on trash directories (hereon called "the trash
#   specification"; see
#   https://specifications.freedesktop.org/trash-spec/trashspec-latest.html),
#   that action moves the target file(s) to a built-in trash directory, and that
#   is exactly what this script does.
#
#   On other hosts, this script uses a custom trash directory (~/.Trash/). The
#   analogy of moving a file to trash is not perfect, as the script does not
#   offer the functionalities of restoring a trashed file to its original
#   location or emptying the trash directory. Rather, it offers an alternative
#   to the 'rm' command, thereby giving the user the peace of mind that they can
#   still undo an unintended deletion before emptying the custom trash
#   directory.
#
# IMPLEMENTATION:
#
#   To determine whether it's running on a host that implements the trash
#   specification, the script tests for the existence of (a) the gio command and
#   (b) either directory $XDG_DATA_HOME/Trash/, or, if that environment variable
#   hasn't bee set, of directory ~/.local/share/Trash/. If the test yields true,
#   the script relies on calling 'gio trash'.
#
#   On other hosts:
#     - There is no built-in trash directory, so the script creates a custom
#       directory ~/.Trash/, unless it already exists. (The script aborts if
#       there is an existing non-directory ~/.Trash.)
#     - The script appends a millisecond-resolution timestamp to all the files
#       it moves to the custom trash directory, to both inform the user of the
#       time of the trashing, and to avoid overwrites.
#     - The user will have to perform an undo by commanding 'mv' on a file or
#       directory moved to ~/.Trash/.
#     - The user will have to empty the custom trash directory by commanding:
#           rm -rf ~/.Trash/* ~/.Trash/.*
#
#   The script will not choke on a nonexistent file. It outputs the final
#   disposition of each filename argument: does not exist, was already in trash,
#   or was moved to trash.
#
# COPYRIGHT WAIVER:
#
#   The author dedicates this Bash script to the public domain by waiving all of
#   their rights to the work worldwide under copyright law, including all
#   related and neighboring rights, to the extent allowed by law. You can copy,
#   modify, distribute, and perform the script, even for commercial purposes,
#   all without asking for permission.

if [ -z "$XDG_DATA_HOME" ] ; then
    xdg_trash_directory=$(realpath ~/.local/share/Trash/)
else
    xdg_trash_directory=$(realpath $XDG_DATA_HOME/Trash/)
fi

gio_command_exists=0
if $(command -v gio > /dev/null 2>&1) ; then
    gio_command_exists=1
fi

host_implements_trash_specification=0
if [[ -d "${xdg_trash_directory}" ]] && (( gio_command_exists == 1 )) ; then
    # Executing on a host that implements the trash specification.
    host_implements_trash_specification=1
    trash_directory="${xdg_trash_directory}"
else
    # Executing on other host, so attempt to use a custom trash directory.
    trash_directory=$(realpath ~/.Trash)
    if [[ -e "${trash_directory}" ]] ; then
        # It exists.
        if [[ ! -d "${trash_directory}" ]] ; then
            # But is not a directory, so abort.
            echo "Error: ${trash_directory} exists, but is not a directory."
            exit 1
        fi
    else
        # It does not exists, so create it.
        mkdir "${trash_directory}"
        echo "Created directory ${trash_directory}"
    fi
fi

# Deal with all filenames (a concept that covers names of both files and
# directories) given as arguments.
for file in "$@" ; do
    file_to_be_trashed=$(realpath -- "${file}")
    file_basename=$(basename -- "${file_to_be_trashed}")
    if [[ ! -e ${file_to_be_trashed} ]] ; then
        echo "does not exist:   ${file_to_be_trashed}"
    elif [[ "${file_to_be_trashed}" == "${trash_directory}"* ]] ; then
        echo "already in trash: ${file_to_be_trashed}"
    else
        # ${file_to_be_trashed} exists and is not yet in the trash directory,
        # so move it there.
        if (( host_implements_trash_specification == 1 )) ; then
            gio trash "${file_to_be_trashed}"
        else
            # Move the file to the custom trash directory, with a new name that
            # appends a millisecond-resolution timestamp to the original.
            head="${trash_directory}/${file_basename}"_TRASHED_ON_
            move_file_to="${head}$(date '+%Y-%m-%d_AT_%H-%M-%S.%3N')"
            while [[ -e "${move_file_to}" ]] ; do
                # Generate a new name with a new timestamp, as the previously
                # generated one denoted an existing file or directory. It's very
                # unlikely that this loop needs to be executed even once.
                move_file_to="${head}$(date '+%Y-%m-%d_AT_%H-%M-%S.%3N')"
            done
            # There is no file or directory named ${move_file_to}, so
            # we can use it as the move target.
            /bin/mv "${file_to_be_trashed}" "${move_file_to}"
        fi
        echo "moved to trash:   ${file_to_be_trashed}"
    fi
done

答え3

ゴミ箱は、Ubuntu では apt-get、Fedora では yum を使用してインストールできる Linux アプリケーションです。コマンドを使用すると、trash listOfFiles指定したものがゴミ箱に移動します。

答え4

まずmove_to_trash関数を定義します。

move_to_trash () {
    mv "$@" ~/.trash
}

次に、rmそのエイリアスを示します。

alias rm='move_to_trash'

rm次のようにバックスラッシュでエスケープすることで、いつでも old を呼び出すことができます\rm

再起動時にゴミ箱ディレクトリを空にする方法はわかりません (システムによってはスクリプトを調べる必要があるかもしれません) が、定期的にディレクトリを空にするタスクrc*を作成することも価値があるかもしれません。cron

関連情報