Hacer que `rm` se mueva a la papelera

Hacer que `rm` se mueva a la papelera

¿Existe algún script/aplicación de Linux que, en lugar de eliminar archivos, los mueva a una ubicación especial de “papelera”? Me gustaría esto como reemplazo rm(tal vez incluso con un alias de este último; hay ventajas y desventajas para eso).

Por "papelera" me refiero a una carpeta especial. Un solo mv "$@" ~/.trashes el primer paso, pero idealmente esto también debería manejar la eliminación de varios archivos con el mismo nombre sin sobrescribir los archivos eliminados más antiguos, y permitirrestaurararchivos a su ubicación original con un simple comando (una especie de "deshacer"). Además, sería bueno si la papelera se vaciara automáticamente al reiniciar (o un mecanismo similar para evitar un crecimiento interminable).

Existen soluciones parciales para esto, pero la acción de “restauración” en particular no es trivial. ¿Existe alguna solución para esto que no dependa de un sistema de basura desde un shell gráfico?

(Aparte, ha habido interminables discusiones sobre si este enfoque está justificado, en lugar de usar copias de seguridad frecuentes y VCS. Si bien esas discusiones tienen razón, creo que todavía hay un nicho para mi solicitud).

Respuesta1

Hay unespecificación (borrador) para basuraen freedesktop.org. Al parecer es lo que suelen implementar los entornos de escritorio.

Una implementación de línea de comando seríabasura-cli. Sin haberlo visto más de cerca, parece proporcionar la funcionalidad que deseas. En caso contrario, díganos hasta qué punto se trata sólo de una solución parcial.

En lo que respecta al uso de cualquier programa como reemplazo/alias rm, existen buenas razones para no hacerlo. Los más importantes para mí son:

  • El programa necesitaría comprender/manejar todas rmlas opciones y actuar en consecuencia
  • Tiene el riesgo de acostumbrarse a la semántica de su "nueva rm" y ejecutar comandos con consecuencias fatales al trabajar en sistemas de otras personas.

Respuesta2

Las respuestas anteriores mencionan comandos trash-cliy rmtrash. Ninguno de ellos se encuentra de forma predeterminada en Ubuntu 18.04, pero el comandogioes. Salidas de mando 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

Probé usandogio trash FILENAMEen la línea de comando, y funciona igual que si seleccioné el archivo en el explorador de archivos y hice clic en el botón SUPR: el archivo se mueve a la carpeta Papelera del escritorio. (El comando no solicita confirmación aunque no utilicé la -fopción).

Eliminar archivos de esta manera es reversible, aunque es más conveniente que redefinirlos rmpor rm -iseguridad y tener que confirmar cada eliminación, lo que aún te deja sin suerte si confirmas accidentalmente una eliminación que no deberías haber hecho.

Agregué alias tt='gio trash'a mi archivo de definiciones de alias; ttes un mnemónico para "tirar a la basura".

Agregado en la edición el 27 de junio de 2018:En las máquinas servidor, no existe un equivalente a un directorio de basura. Escribí el siguiente script Bash que hace el trabajo; en las máquinas de escritorio, usa gio trash, y en otras máquinas, mueve los archivos proporcionados como parámetros a un directorio de papelera que crea. Se prueba que el guión funciona; Lo uso todo el tiempo yo mismo.Guión actualizado el 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

Respuesta3

basura-clies una aplicación de Linux que se puede instalar usando apt-get en Ubuntu o yum en Fedora. El uso del comando trash listOfFilesmoverá lo especificado a su papelera.

Respuesta4

Comience definiendo una move_to_trashfunción:

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

Entonces alias rma eso:

alias rm='move_to_trash'

Siempre puedes llamar a old rmponiendo como escape una barra invertida, como esta: \rm.

No sé cómo hacer que el directorio de la papelera se vacíe al reiniciar (dependiendo de su sistema, es posible que deba consultar los rc*scripts), pero también podría valer la pena crear una crontarea que vacíe el directorio periódicamente.

información relacionada