web-dev-qa-db-ja.com

「rm」をゴミ箱に移動します

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

「ゴミ箱」とは、特別なフォルダを意味します。独身者 mv $* ~/.trashは最初のステップですが、理想的には、古いゴミ箱のファイルを上書きせずに、同じ名前の複数のファイルをゴミ箱に入れ、簡単なコマンド(ある種のコマンド)でrestoreファイルを元の場所に戻すことができます「元に戻す」)。さらに、再起動時にゴミ箱が自動的に空になった場合(または、無限の成長を防ぐための同様のメカニズム)であれば、それは素晴らしいことです。

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

(余談ですが、頻繁にバックアップやVCSを使用するのではなく、このアプローチが正当であるかどうかについては無限の議論がありました。これらの議論には意味がありますが、私の要求にはまだニッチがあると思います。)

55
Konrad Rudolph

Freedesktop.orgに ゴミ箱の仕様(ドラフト) があります。これは明らかに、デスクトップ環境で通常実装されるものです。

コマンドラインの実装は trash-cli になります。よく見ることなく、それはあなたが望む機能性を提供するようです。そうでない場合は、これが部分的な解決策にすぎないことを教えてください。

rmの置換/エイリアスとして任意のプログラムを使用することに関する限り、そうしないことには十分な理由があります。私にとって最も重要なのは:

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

以前の回答では、コマンド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オプションを使用していなくても、コマンドは確認を求めません。)

この方法でファイルを削除することは元に戻せますが、安全のためにrmrm -iに再定義するよりも便利であり、削除ごとに確認する必要があります。持っていません。

エイリアス定義ファイルにalias tt='gio trash'を追加しました。 ttはTo Trashのニーモニックです。

2018-06-27の編集時に追加:サーバーマシンには、ごみ箱ディレクトリに相当するものはありません。この作業を行う次のBashスクリプトを作成しました。デスクトップマシンではgio trashを使用し、他のマシンでは、パラメータとして指定されたファイルを、作成したごみ箱ディレクトリに移動します。 2019-09-05に更新されたスクリプト

#!/bin/bash
#
# move-to-trash
#
# Teemu Leisti 2019-09-05
#
# This script moves the files given as arguments to the trash directory, if they
# are not already there. It works both on (Gnome) desktop and server hosts.
#
# The script is intended as a command-line equivalent of deleting a file from a
# graphical file manager, which, in the usual case, moves the deleted file(s) to
# a built-in trash directory. On server hosts, the analogy is not perfect, as
# the script does not offer the functionality of restoring a trashed file to its
# original location, nor that of emptying the trash directory; rather, it offers
# an alternative to the 'rm' command, giving the user the peace of mind that
# they can still undo an unintended deletion before emptying the trash
# directory.
#
# To determine whether it's running on a desktop Host, the script tests for the
# existence of the gio utility and of directory ~/.local/share/Trash. In case
# both exist, the script relies on the 'gio trash' command. Otherwise, it treats
# the Host as a server.
#
# There is no built-in trash directory on server hosts, so the first invocation
# of the script creates directory ~/.Trash/, unless it already exists.
#
# The script appends a millisecond-resolution time stamp to all the files it
# moves to the trash directory, both to inform the user of the time of the
# deletion, and to avoid overwrites when moving a file to trash.
#
# The script will not choke on a nonexistent file. It outputs the final
# disposition of each argument: does not exist, was already in trash, or was
# moved to trash.


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

# Exit on using an uninitialized variable, and on a command returning an error.
# (The latter setting necessitates appending " || true" to those arithmetic
# calculations and other commands that can return 0, lest the Shell interpret
# the result as signalling an error.)
set -eu

is_desktop=0

if [[ -d ~/.local/share/Trash ]] && (( gio_command_exists == 1 )) ; then
    is_desktop=1
    trash_dir_abspath=$(realpath ~/.local/share/Trash)
else
    trash_dir_abspath=$(realpath ~/.Trash)
    if [[ -e $trash_dir_abspath ]] ; then
        if [[ ! -d $trash_dir_abspath ]] ; then
            echo "The file $trash_dir_abspath exists, but is not a directory. Exiting."
            exit 1
        fi
    else
        mkdir $trash_dir_abspath
        echo "Created directory $trash_dir_abspath"
    fi
fi

for file in "$@" ; do
    file_abspath=$(realpath -- "$file")
    file_basename=$(basename -- "$file_abspath")
    if [[ ! -e $file_abspath ]] ; then
        echo "does not exist:   $file_abspath"
    Elif [[ "$file_abspath" == "$trash_dir_abspath"* ]] ; then
        echo "already in trash: $file_abspath"
    else
        if (( is_desktop == 1 )) ; then
            gio trash "$file_abspath" || true
        else
            # The name of the moved file shall be the original name plus a
            # millisecond-resolution timestamp.
            move_to_abspath="$trash_dir_abspath/$file_basename-$(date '+%Y-%m-%d-at-%H-%M-%S.%3N')"
            while [[ -e "$move_to_abspath" ]] ; do
                # Generate a new name with a new timestamp, as the previously
                # generated one denoted an existing file.
                move_to_abspath="$trash_dir_abspath/$file_basename-$(date '+%Y-%m-%d-at-%H-%M-%S.%3N')"
            done
            # We're now almost certain that the file denoted by name
            # $move_to_abspath does not exist, as for that to be the case, an
            # extremely unlikely run condition would have had to take place:
            # some other process would have had to create a file with the name
            # $move_to_abspath after the execution of the existence test above.
            # However, to make absolute sure that moving the file to the trash
            # directory will always be successful, we shall give the '-f'
            # (force) flag to the 'mv' command.
            /bin/mv -f "$file_abspath" "$move_to_abspath"
        fi
        echo "moved to trash:   $file_abspath"
    fi
done
9
Teemu Leisti

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

9
namu

これは、名前の衝突に対処し、1秒間に複数のファイルを削除しない限り、同じパス上で複数の削除済みファイルを許可する迅速でダーティなゴミシステムです。

警告:このコードをブラウザに直接入力しました。おそらく壊れています。本番データには使用しないでください。

trash_root=~/.trash
mkdir "$trash_root"
newline='
'
trash () (
  time=$(date +%Y%m%d%H%M%S)
  for path; do
    case $path in /*) :;; *) path=$PWD/$path;; esac
    mkdir "$trash_root${path%/*}"
    case ${path##*/} in
      ?*.*) ext="${path##*.}"; ext="${ext##*$newline}";;
      *) ext="";;
    esac
    metadata="Data: $hash.$ext
Date: $time
Path: $path
"
    hash=$(printf %s "$metadata" | sha1sum)
    printf %s "$metadata" "$trash_root/$hash-$time-metadata"
    mv "$path" "$trash_root/$hash.$ext"
  done
)

untrash () (
  IFS='
  '
  root=$PWD
  cd "$trash_root" || return 2
  err=0
  for path; do
    if [ -e "$path" ]; then
      echo 1>&2 "Not even attempting to untrash $path over an existing file"
      if [ $err -gt 2 ]; then err=2; fi
      continue
    fi
    case $path in /*) :;; *) path=$root/$path;; esac 
    if metadata=$(grep -l -F -x "Path: $path" *-metadata |
                  sort -t - -k 2 | tail -n 1); then
      mv "${metadata%%-*}".* "$path"
    else
      echo 1>&2 "$path: no such deleted file"
      if [ $err -gt 1 ]; then err=1; fi
    fi
  done
  return $err
)

既知の問題点:

  • 同じファイルを同時に数回削除しようとすると、うまく処理できません。
  • ゴミ箱ディレクトリは巨大になるかもしれません、ファイルはハッシュの最初の数桁に基づいてサブディレクトリに送られるべきです。
  • trashはファイル名の改行に対応する必要がありますが、untrashgrepに依存し、メタデータファイルで改行がエスケープされないため、対応しません。

これを行う rmtrash と呼ばれる小さなユーティリティがあります。

-r-fなどのパラメータには応答しないようです(基本的にはファイル/ディレクトリを〜/ .Trashディレクトリに移動しているようです)。同じ名前(同じ名前のファイル/ディレクトリに「コピー」を追加します)。

Brewでインストールするには

brew install rmtrash
alias rm='rmtrash' >> ~/.bashrc
4
FreePender

move_to_trash 関数:

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

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

alias rm='move_to_trash'

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

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

2
rahmu

私のデルを使用できます:

http://fex.belwue.de/fstools/del.html

delは、.del /サブディレクトリ内のファイルを移動します(そして戻します)。

使用量:del [-v] [-u]ファイル
 del [-v] -p [-r] [-d日] [ディレクトリ] 
 del [-v] -l 
オプション:-v詳細モード
 -uファイルの削除を取り消します
 -p削除されたファイルを削除します[-d日より古い] 
 -r再帰的(すべてのサブディレクトリ)
 -l削除されたファイルのリスト
例:del * .tmp#すべての* .tmpファイルを削除
 del -u project.pl#プロジェクトの削除を取り消す.pl 
 del -vprd 2#2日以上経過した削除済みファイルの詳細なパージ
1
Framstag

KDE 4.14.8では、次のコマンドを使用してファイルをゴミ箱に移動しました(まるでDolphinで削除されたかのように):

kioclient move path_to_file_or_directory_to_be_removed trash:/

付録I:コマンドについて

    ktrash --help
...
    Note: to move files to the trash, do not use ktrash, but "kioclient move 'url' trash:/"

付録II:関数(そして、それを.bashrcにソースします)

function Rm {
    if [[ "$1" == '--help' ]] ; then
        echo 'USAGE:'
        echo 'Rm --help # - show help'
        echo 'Rm file1 file2 file3 ...'
        echo 'Works for files and directories'
        return
    fi
    for i in "$@" ;
    do
        kioclient move $i trash:/ && echo "$i was trashed"
    done
}
0
user3804598