it-swarm.com.de

Bewegen Sie `rm` in den Papierkorb

Gibt es ein Linux-Skript/eine Linux-Anwendung, mit der Dateien nicht gelöscht, sondern an einen speziellen Speicherort verschoben werden? Ich möchte dies als Ersatz für rm (vielleicht sogar als Alias ​​für Letzteres; dafür gibt es Vor- und Nachteile).

Mit "Papierkorb" meine ich einen speziellen Ordner. Ein einzelnes mv $* ~/.trash ist ein erster Schritt, aber idealerweise sollte dies auch das Löschen mehrerer gleichnamiger Dateien behandeln, ohne ältere Papierkorbdateien zu überschreiben, und es ermöglichen, Wiederherstellen Dateien mit einem einfachen Befehl (einer Art von) an ihren ursprünglichen Speicherort zu verschieben "rückgängig machen"). Außerdem wäre es schön, wenn der Papierkorb beim Neustart automatisch geleert würde (oder ein ähnlicher Mechanismus, um endloses Wachstum zu verhindern).

Hierfür gibt es Teillösungen, aber insbesondere die Aktion "Wiederherstellen" ist nicht trivial. Gibt es dafür Lösungen, die nicht auf einem Müllsystem aus einer grafischen Shell basieren?

(Abgesehen davon gab es endlose Diskussionen darüber, ob dieser Ansatz gerechtfertigt ist, anstatt häufige Backups und VCS zu verwenden. Obwohl diese Diskussionen einen Sinn haben, glaube ich, dass es immer noch eine Nische für meine Anfrage gibt.)

55
Konrad Rudolph

Es gibt eine Spezifikation (Entwurf) für Papierkorb auf freedesktop.org. Es ist anscheinend das, was normalerweise von Desktop-Umgebungen implementiert wird.

Eine Befehlszeilenimplementierung wäre trash-cli . Ohne genauer hinzuschauen, scheint es die gewünschte Funktionalität zu bieten. Wenn nicht, teilen Sie uns mit, inwieweit dies nur eine Teillösung ist.

Wenn Sie ein Programm als Ersatz/Alias ​​für rm verwenden, gibt es gute Gründe, dies nicht zu tun. Am wichtigsten für mich sind:

  • Das Programm müsste alle Optionen von rm verstehen/handhaben und entsprechend handeln
  • Es besteht die Gefahr, dass Sie sich an die Semantik Ihres "neuen rm" gewöhnen und Befehle mit schwerwiegenden Folgen ausführen, wenn Sie an den Systemen anderer Personen arbeiten
37
zpea

Die vorherigen Antworten erwähnen die Befehle trash-cli Und rmtrash. Keiner von beiden wird standardmäßig unter Ubuntu 18.04 gefunden, aber der Befehl gio lautet. Befehlsausgabe 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

Ich habe mit gio trash FILENAME in der Befehlszeile getestet und es funktioniert so, als hätte ich die Datei im Dateibrowser ausgewählt und auf die Schaltfläche ENTF geklickt: Die Datei wird in den Papierkorb des Desktops verschoben Mappe. (Der Befehl fordert nicht zur Bestätigung auf, obwohl ich die Option -f Nicht verwendet habe.)

Das Löschen von Dateien auf diese Weise ist umkehrbar, während es aus Sicherheitsgründen bequemer ist, rm als rm -i Zu definieren und jede Löschung bestätigen zu müssen. Wenn Sie versehentlich eine Löschung bestätigen, haben Sie immer noch kein Glück sollte nicht haben.

Ich habe alias tt='gio trash' Zu meiner Alias-Definitionsdatei hinzugefügt. tt ist eine Mnemonik für To Trash.

Hinzugefügt bei der Bearbeitung am 27.06.2018 : Auf Server-Computern gibt es kein Äquivalent zu einem Papierkorbverzeichnis. Ich habe das folgende Bash-Skript geschrieben, das den Job erledigt. Auf Desktop-Computern wird gio trash verwendet, und auf anderen Computern werden die als Parameter angegebenen Dateien in ein von ihm erstelltes Papierkorbverzeichnis verschoben. Skript aktualisiert am 05.09.2019.

#!/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 "[email protected]" ; 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 ist eine Linux-Anwendung, die mit apt-get in Ubuntu oder yum in Fedora installiert werden kann. Mit dem Befehl trash listOfFiles verschiebt das angegebene in den Papierkorb.

9
namu

Hier ist ein schnelles und schmutziges Papierkorbsystem, das mit Namenskonflikten fertig wird und sogar mehrere gelöschte Dateien auf demselben Pfad zulässt, solange Sie nicht mehr als eine Datei pro Sekunde löschen.

Warnung: Ich habe diesen Code direkt in meinen Browser eingegeben. Es ist wahrscheinlich kaputt. Verwenden Sie es nicht für Produktionsdaten.

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
)

Bekannte Probleme:

  • Wird nicht ordnungsgemäß verarbeitet, wenn Sie versuchen, dieselbe Datei mehrmals gleichzeitig zu löschen.
  • Das Papierkorbverzeichnis kann sehr groß werden. Die Dateien sollten basierend auf den ersten Ziffern des Hashs in Unterverzeichnisse gesendet werden.
  • trash sollte mit Zeilenumbrüchen in Dateinamen umgehen, untrash jedoch nicht, da es auf grep beruht und die Zeilenumbrüche nicht in der Metadatendatei maskiert werden.

Es gibt ein kleines Dienstprogramm namens rmtrash , das dies tut.

Es scheint nicht auf Parameter wie -r Oder -f Zu reagieren (es scheint im Wesentlichen nur die Datei/das Verzeichnis in das Verzeichnis ~/.Trash zu verschieben), aber es wird nicht überschrieben gleichnamige Dateien (an gleichnamige Dateien/Verzeichnisse wird "Kopieren" angehängt).

Mit Gebräu installieren

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

Beginnen Sie mit der Definition eines move_to_trash Funktion:

move_to_trash () {
    mv "[email protected]" ~/.trash
}

Dann Alias ​​rm dazu:

alias rm='move_to_trash'

Sie können das alte rm jederzeit aufrufen, indem Sie es mit einem Backslash wie folgt maskieren: \rm.

Ich weiß nicht, wie ich das Papierkorbverzeichnis beim Neustart leer machen soll (abhängig von Ihrem System müssen Sie möglicherweise das rc* scripts), aber es kann sich auch lohnen, eine cron Task zu erstellen, die das Verzeichnis regelmäßig leert.

2
rahmu

Sie können mein del verwenden:

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

del verschiebt Dateien in ein .del/Unterverzeichnis (und zurück)

 Verwendung: del [-v] [-u] Datei (en) 
 del [-v] -p [-r] [-d Tage] [Verzeichnis] ​​
 del [-v] -l 
 Optionen: -v ausführlicher Modus 
 -u nicht wiederhergestellte Datei (en) 
 -p gelöschte Dateien löschen [älter als -d Tage] 
 -r rekursiv (alle Unterverzeichnisse) 
 -l Liste der gelöschten Dateien 
 Beispiele: del * .tmp # Alle * .tmp-Dateien löschen 
 del -u project.pl # Projekt wiederherstellen .pl 
 del -vprd 2 # Ausführliche Löschung gelöschter Dateien, die älter als 2 Tage sind 
1
Framstag

In KDE 4.14.8 habe ich den folgenden Befehl verwendet, um Dateien in den Papierkorb zu verschieben (als ob sie in Dolphin entfernt worden wären):

kioclient move path_to_file_or_directory_to_be_removed trash:/

Anhang I: Ich habe über den Befehl mit gefunden

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

Anhang II: Die Funktion (dann in Ihrer .bashrc-Quelle)

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 "[email protected]" ;
    do
        kioclient move $i trash:/ && echo "$i was trashed"
    done
}
0
user3804598