¿Cómo mover archivos a la papelera desde la línea de comandos?

Hago mucho trabajo de terminal, y hoy tuve la experiencia de escribir

rm fileInQuestion.txt

Antes de descubrir que realmente necesitaba fileInQuestion.txt. Si lo hubiera eliminado en la GUI, lo habría sacado de la Papelera. Me gustaría saber si es posible sobrecargar 'rm' en la Terminal de tal manera que envíe el archivo/archivos a la Papelera al salir.

Hay programas que pueden recuperar archivos borrados (¡siempre que esos sectores en el disco duro no se sobrescriban mientras tanto!). Cuando esto suceda, deberías usar uno de esos...
Consulte también askubuntu.com/q/468721/250556 para los usuarios de Google que buscan la eliminación de archivos de ubuntu/debian/linux.

Respuestas (15)

No recomendaría crear un alias rm, mvya que podría tener el hábito de rmno eliminar archivos de forma permanente y luego tener problemas en otras computadoras o en otras cuentas de usuario cuando se elimine de forma permanente.

Escribí un conjunto de secuencias de bashcomandos que agregan más herramientas de línea de comandos similares a Mac OS X (además de varias de las integradas como open, pbcopy, pbpaste, etc.), lo más importante trash. Mi versión de trashhará todas las cosas correctas que el alias rmno hará (y espero que nada malo, pero lo he estado usando en mis propias Mac durante algunos años sin perder datos), incluido: cambiar el nombre del archivo como lo hace Finder si ya existe un archivo con el mismo nombre, colocar los archivos en la carpeta Papelera correcta en volúmenes externos; también tiene algunas sutilezas añadidas, como: intenta usar AppleScript cuando está disponible para obtener el agradable sonido de basura y demás (pero no lo requiere, por lo que aún puede usarlo a través de SSH cuando ningún usuario ha iniciado sesión), puede le dará el tamaño de la papelera en todos los volúmenes.

Puede obtener mi suite tools-osx de mi sitio o la última y mejor versión del repositorio de GitHub .

También hay un trashcomando desarrollado por Ali Rantakari , pero no lo he probado yo mismo.

Excelente respuesta, mucho mejor que la mía!
He usado trashRantakari durante bastante tiempo y realmente puedo dar fe de ello. Está compilado en Objective-C y utiliza hábilmente las API estándar del sistema de archivos y, en caso de que falle (es decir, el usuario no tiene suficientes derechos), llama al Finder para que deseche los archivos (efectivamente solicitando la autenticación). Puede leer más información trashen hasseg.org/blog .
la basura también está disponible a través del administrador de paquetes brew. solo usa: brew install trash.
@ landon9720 Buen punto. Y, para aclarar a los demás, el trashcomando disponible a través de Homebrew es el de Alai Rantakari (ver la brewfórmula ).
@ landon9720 ¡ámame un poco de basura casera!
Acabo de ver tu página de git: ¿336 líneas de código bash para mover un archivo a la papelera? ;)
@CousinCocaine Jaja, sí, le vendría bien un poco de consolidación después de todos estos años. Dicho esto, está bien comentado y admite una gran cantidad de funcionalidades (basura en varios volúmenes, mover a la papelera directamente o mediante AppleScript, vaciar y vaciar de forma segura, etc.), por lo que no sería particularmente corto de todos modos. :)
@morgant, de hecho. Se ve limpio y muy completo. Bonito.
He estado usando el trashcomando de Ali Rantakari durante años y me gusta. Pero actualicé a Yosemite y dejó de funcionar. Me sale un error diciendo -bash: /usr/bin/trash: /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby: bad interpreter: No such file or directory. ¿Alguien sabe cómo arreglar esto?
Pude corregir el error ejecutando brew remove trashy luego brew install trash.
¿Las respuestas de solo enlace son realmente aceptables aquí? No están en desbordamiento de pila. No hay nada aquí que realmente responda la pregunta, aparte de un enlace que puede fallar en cualquier momento.
@xaxxon Aprecio tu pregunta. Como autor de esta respuesta, mi objetivo original era responder la pregunta en el primer párrafo (recomendando no usar alias rm) y luego proporcionar soluciones alternativas. Sin duda, otros parecen sentir que mi respuesta respondió más completamente a la pregunta, pero me complace ampliar mi primer párrafo si cree que sería útil.
@morgant Desaconsejar algo es un comentario, no una respuesta.
el sitio está caído. rotura.
@CarterPape Sé por qué tuviste que poner 'rip' después de 'site is down', elección inteligente :))
El sitio está respaldado, aunque la mayoría de las actualizaciones se han realizado en el repositorio de GitHub.
Muchos comentarios aquí hablan sobre el trashcomando alternativo instalado por brew install trash. Para ser claros, esa papelera ya no usa el Finder de forma predeterminada, por lo que "Volver a colocar" no funcionará a menos que use una bandera. Incluso cuando usa la bandera, a menudo falla (razón por la cual se cambió el valor predeterminado). Entonces, el guión de morgant es de mayor calidad. Se puede instalar usando zinit con este comandozinit wait'1' lucid light-mode as"program" pick"src/trash" for morgant/tools-osx

La herramienta de línea de comandos de basura se puede instalar a través brew install trashde o port install trash.

Le permite restaurar archivos desechados a través de la línea de comandos o el Finder.

¡Qué solución más elegante!
También disponible en macports:port install trash
cada vez que lo intento brew install trashme sale esto: pastebin.com/N92cM7d8
@BenC.R.Leggiero, llevaría ese problema a github.com/ali-rantakari/trash/issues . ¿Lo hiciste tú brew updateprimero? Funciona bien en mi extremo.
@PaulWenzel sí, y parece actualizarse bien. Publicaré un problema.
Parece una solución bastante pesada para algo que podemos hacer con un simple script de Python .

Tengo un ejecutable llamado remen algún lugar de mi $PATHcon el siguiente contenido:

EDITAR: el código a continuación es una versión revisada y mejorada en colaboración con Dave Abrahams :

#!/usr/bin/env python
import os
import sys
import subprocess

if len(sys.argv) > 1:
    files = []
    for arg in sys.argv[1:]:
        if os.path.exists(arg):
            p = os.path.abspath(arg).replace('\\', '\\\\').replace('"', '\\"')
            files.append('the POSIX file "' + p + '"')
        else:
            sys.stderr.write(
                "%s: %s: No such file or directory\n" % (sys.argv[0], arg))
    if len(files) > 0:
        cmd = ['osascript', '-e',
               'tell app "Finder" to move {' + ', '.join(files) + '} to trash']
        r = subprocess.call(cmd, stdout=open(os.devnull, 'w'))
        sys.exit(r if len(files) == len(sys.argv[1:]) else 1)
else:
    sys.stderr.write(
        'usage: %s file(s)\n'
        '       move file(s) to Trash\n' % os.path.basename(sys.argv[0]))
    sys.exit(64) # matches what rm does on my system

Se comporta exactamente de la misma manera que eliminar desde el Finder. (Ver entrada de blog aquí .)

Esto debería tener más puntos en mi opinión. Debido a que es AppleScript, utiliza el proceso de papelera real para mover el archivo a la papelera, lo que significa que se comportará exactamente igual. Sin embargo, es una pena que no se haya proporcionado una sola línea.
Bueno, alguien lo rechazó el 31 de octubre de 2015 a las 10:26, ¡precisamente al mismo tiempo que alguien más estaba publicando una respuesta a esta pregunta!
Esta respuesta es una lección objetiva sobre cómo hacer las cosas bien. Funciona con comodines de shell y funciona a través del Finder. No reinventa ninguna rueda, y es tan simple como puede ser. Lo puse en mi ~/bin, lo llamé trashy funcionó la primera vez, lo que me permitió eliminar una gran cantidad de archivos de manera más eficiente que si tuviera que hacer clic en ellos en las ventanas del Finder. Mucha gratitud. ¡Espero que publiques más respuestas!
Desafortunadamente, el script no maneja los 'caracteres en los nombres de los archivos. Estaba tratando de usarlo con uno de esos archivos "(copia de conflicto de John Doe)" que a veces crea Dropbox, cuando falló en mí.
Esta versión maneja cotizaciones. Cambia un poco el comportamiento del manejo de errores, que en la versión anterior parece no estar resuelto con mucho cuidado (errores en stdout en lugar de stderr, sin código de salida), pero el error que se obtiene osascriptcuando el archivo no existe no es hermoso, por lo que es posible que desee afinar esa parte.
Buen trabajo. Esta versión incorpora esos cambios y también (1) intenta imitar el comando de shell rmtanto como sea posible en términos de mostrar mensajes cuando los archivos no existen, y (2) recopila todo en una sola osascriptllamada.
@DaveAbrahams: Esta es claramente LA respuesta :) Para ser "unixly correcto" (UC), el script debe instalarse como /usr/local/bin(o, /usr/local/sharesi lo prefiere). Asigne un nombre al archivo /usr/local/bin/trashy: sudo chmod a+rx usr/local/bin/trash.

Utilice el comando de terminal osascript, el intérprete de AppleScript.

osascript -e "tell application \"Finder\" to delete POSIX file \"${PWD}/${InputFile}\""

Esto le dice a AppleScript que le diga a Finder que envíe el archivo a la papelera.

Se necesita PWD para rutas de archivo relativas, ya que AppleScript no lo maneja bien.

¡Simple, efectivo y sin necesidad de instalar nada! Bonito.

un enfoque moderno usando swift

https://github.com/reklis/recycle

//
// main.swift
// recycle
//
// usage: recycle <files or directories to throw out>
//

import Foundation
import AppKit

var args = NSProcessInfo.processInfo().arguments
args.removeAtIndex(0) // first item in list is the program itself

var w = NSWorkspace.sharedWorkspace()
var fm = NSFileManager.defaultManager()

for arg in args {
    let path = arg.stringByStandardizingPath;
    let file = path.lastPathComponent
    let source = path.stringByDeletingLastPathComponent

    w.performFileOperation(NSWorkspaceRecycleOperation,
        source:source,
        destination: "",
        files: [file],
        tag: nil)
}
Si bien este enlace puede responder la pregunta, es mejor incluir las partes esenciales de la respuesta aquí y proporcionar el enlace como referencia. Las respuestas de solo enlace pueden dejar de ser válidas si la página enlazada cambia.
@jherran gracias por el recordatorio, agregué un segmento de código
Esta es mi respuesta preferida porque usa la misma lógica subyacente y las mismas API que la GUI.
Ahora, si tan solo hubiera una versión de Python que evitara la necesidad de un binario de 3 MB para hacer una llamada al sistema.

Encontré un código bastante bueno que se puede agregar al final del perfil de lote del usuario y hace rmque los archivos se muevan a la papelera cada vez que se ejecuta.

nano ~/.bash_profile

#... append at the end
function rm () {
  local path
  for path in "$@"; do
    # ignore any arguments
    if [[ "$path" = -* ]]; then :
    else
      # remove trailing slash
      local mindtrailingslash=${path%/}
      # remove preceding directory path
      local dst=${mindtrailingslash##*/}
      # append the time if necessary
      while [ -e ~/.Trash/"$dst" ]; do
        dst="`expr "$dst" : '\(.*\)\.[^.]*'` `date +%H-%M-%S`.`expr "$dst" : '.*\.\([^.]*\)'`"
      done
      mv "$path" ~/.Trash/"$dst"
    fi
  done
}

fuente: http://hints.macworld.com/article.php?story=20080224175659423

Esto es muy inteligente, pero aún así no lo recomendaría. Es inteligente porque está en el perfil de bash para el usuario y, por lo tanto, solo el usuario puede ejecutar esta versión de la función escribiéndola, los scripts que se basan en rm seguirán llamando al original. Pero no recomendaría hacer esto porque el usuario se acostumbrará a actuar de esta manera cuando no lo hace en otras máquinas. Voy a usar esto, pero cambie el nombre de la función a "basura"
Estoy usando la misma función con dos cambios: ① Corregí un error en la función que hace que se cambie el nombre de cualquier carpeta a la marca de tiempo, si se completó con tabulación para incluir una barra inclinada final: Esto requiere los siguientes cambios: Reemplazar el línea local dst=${path##*/}con local dst=${mindtrailingslash##*/}e insertando otra línea justo antes de la que dice local mindtrailingslash=${path%/}. ② Yo uso el nombre function rr. Así, no interfiere con plain rm, pero el nombre es igualmente corto y rápido de escribir (cualquier otro nombre serviría).
Cambie el nombre de rm()a rmt(): de esta manera, puede seguir usando el rmcomando cuando lo desee. Pienso en rmt en mi cabeza como remove to trash:D

Hay dos utilidades instalables a través de Homebrew que pueden lograr esto:

  1. basura

    Este es un pequeño programa de línea de comandos para OS X que mueve archivos o carpetas a la papelera. La USP de este comando es que permite restaurar fácilmente los archivos. Un comando para eliminar archivos/carpetas no sirve de nada si no puede restaurar archivos/carpetas después de eliminarlos. Desde el sitio web del comando:

De forma predeterminada, la papelera le pide a Finder que mueva los archivos/carpetas especificados a la papelera en lugar de llamar a la API del sistema para hacerlo debido a la función "devolver" que solo funciona cuando se envían archivos a la papelera a través de Finder.


-F

Pídale a Finder que mueva los archivos a la papelera, en lugar de usar la API del sistema. Esto es más lento, pero utiliza la interfaz de usuario de Finder (por ejemplo, sonidos) y garantiza que la función "retroceder" funcione.

-l

Enumere los elementos que se encuentran actualmente en la papelera. Si se utiliza este argumento, no es necesario especificar ningún archivo.

-mi

Vacíe la basura. trash pide confirmación antes de ejecutar esta acción. Si se utiliza este argumento, no es necesario especificar ningún archivo.

Para instalar trash, ejecute lo siguiente en la Terminal:

brew install trash.


  1. basura

    Una herramienta de línea de comandos que mueve archivos a la papelera. Desde la página del manual del comando:

Este comando mueve los archivos a la papelera en lugar de eliminarlos por completo del sistema de archivos. Muy útil si decides que quieres ese archivo después de todo...


-u NOMBRE DE USUARIO

un argumento opcional. Esto moverá el archivo a la papelera del usuario especificado. Tenga en cuenta que necesita suficientes privilegios para lograr esto.

Para instalar rmtrash, ejecute lo siguiente en la Terminal:

brew install rmtrash.

Aquí hay una solución de una línea bastante trivial para agregar a su perfil bash. Tenga en cuenta que sobrescribirá algo con el mismo nombre en la papelera.

trash() { mv -fv "$@" ~/.Trash/ ; }

Uso:

• ~/Desktop $$$ touch a b c
• ~/Desktop $$$ ls
a b c
• ~/Desktop $$$ trash a b c
a -> /Users/ryan.tuck/.Trash/a
b -> /Users/ryan.tuck/.Trash/b
c -> /Users/ryan.tuck/.Trash/c
• ~/Desktop $$$ ls
• ~/Desktop $$$
He editado en consecuencia, ¡gracias por la entrada!

Esta es una mejora de las respuestas dadas por Antony Smith y cde .

El problema de incrustar un nombre de archivo en una cadena que se pasa a osascripttravés -ees que, en los sistemas modernos similares a Unix, los nombres de archivo pueden contener comillas, en el sentido de que partes del nombre de archivo podrían ejecutarse como AppleScript.

Una forma más segura de hacer esto es leer el nombre del archivo desde una variable de entorno:

trash() (
    : "${1:?}"
    case $1 in
        (/*) FNAME="$1" ;;
        (*)  FNAME="$(pwd)/$1"
    esac
    export FNAME
    exec osascript <<-EOF >/dev/null
        set fName to system attribute "FNAME"
        tell application "Finder" to delete my (POSIX file fName)
    EOF
)

Si agrega esta función a su .bashrco .zshrc, puede llamar trashdesde la línea de comando. EDITAR: aunque convertir esto en una función que sea realmente útil requiere más trabajo, por supuesto.

Si bien es posible rmmover archivos a la Papelera en lugar de eliminarlos, desaconsejaría llevar la mentalidad de la red de seguridad de las interfaces gráficas de usuario al shell de UNIX. Hay muchas formas de causar daños graves utilizando el terminal. El mejor consejo en mi humilde opinión es simplemente pensar dos veces antes de presionar la entertecla en una ventana de shell.

Si desea rmrecordarle que está a punto de eliminar un archivo, considere usar el siguiente alias (para /bin/bashcolocar esta línea en .bashrcsu directorio de inicio):

alias rm "rm -i"

Esto hará que se rmconfirme la solicitud antes de intentar eliminar cada archivo.

Si tiene TimeMachine ejecutándose (¡eso espero!), siempre puede obtener su archivo de la copia de seguridad. De esta manera puede perder como máximo una hora de trabajo. Lo cual es bastante malo, por supuesto. ¡Así que piénsalo de nuevo antes de presionar esa entertecla!

¡No lo hagas! Los scripts del instalador pueden usar rmy bloquearse con el alias rm -i.
@OldPro: .bashrcsolo se ejecuta si el shell es interactivo. ¡ Consulte la página del manual !
Aconsejaría no eliminar las redes de seguridad o advertir a otros que lo hagan.
Iré en contra de los detractores y diré que uso este truco con gran efecto, pero definitivamente solo debe hacerse conociendo las trampas. Dos que no se mencionan son que entrena su cerebro que rmes más seguro de lo que es, lo que lo meterá en problemas en otros sistemas. Además, si usa -f, -ise ignora por completo. Dicho esto, esta es una buena red de seguridad. Una mejor es nunca usar rma favor de un rmialias ( alias rmi="rm -i") o la trashutilidad relevante. Además, agregaré que todos deberían haber puesto [ -f ~/.bashrc ] && source ~/.bashrcsu .bash_profileya.

Desechar correctamente las cosas (para que sea definitivamente recuperable) es más complicado que simplemente un mvarchivo ~/.Trash.

osx-trash podría ser lo que estás buscando. ( Advertencia emptor : no lo he probado y no puedo garantizar qué tan seguro es).

Echa un trash-clivistazo Funciona multiplataforma, sin sonido basura y es compatible con Put Back.

Puede instalarlo con (requiere Node.js ) :

$ npm install --global trash-cli

Como alternativa, si no desea utilizar Node.js, puede instalar el binario nativo osx-trashmanualmente.

En su .bashrc (o donde sea que guarde los parámetros para su shell), intente agregar un alias que cambie el comportamiento de rm para mover cosas a ~/.Trash, como en:

alias rm='move/to/.Trash'

Sin embargo, este alias está lejos de ser trivial de implementar (al menos para mí), porque el uso de mv (el principal candidato para usar en este trabajo) es

mv file where

por lo tanto, tener un alias que coloque la parte "dónde" delante del archivo que se va a mover puede ser bastante incompleto. Lo investigaré y podría obtener consejos más sustanciales.

EDITAR: acabo de intentar agregar lo siguiente a mi .bashrc, y funciona:

function trash { mv "$@" ~/.Trash ; }

Es mucho más primitivo que otras sugerencias, pero evita instalar cosas nuevas.

La creación de alias rmpara cualquier cosa es peligrosa porque puede romper los scripts del instalador. Aprendí esto de la manera más difícil cuando hice un alias rmy las rm -iinstalaciones se bloquearon.
@Old Pro, ese es el alias que uso para rm en todas mis computadoras, desde el día 0, y nunca tuve problemas por eso. ¿Te importaría dar un ejemplo?
No recuerdo la aplicación específica que estaba instalando, pero sí recuerdo que la instalación (probablemente una actualización) se colgó y me tomó alrededor de un mes darme cuenta de que se debía a que se usó un script de instalación en rmlugar de rm -fy el script estaba colgado esperando. para confirmar que estaba bien eliminar algún archivo. Eliminar el alias de mi .bashrc permitió que se completara la instalación y desde entonces me he abstenido de usar ese alias en OS X, aunque todavía lo uso en todos los demás sistemas Unix. No estoy seguro de qué hará tu alias con rm -f someFile.
@OldPro: .bashrcsolo se usa para shells interactivos . Si ejecuta ./install.shun nuevo proceso se inicia y el alias no estará activo. Sin embargo, si ejecuta . install.shsu proceso actual, se ejecutará el instalador y el alias estará activo. RTF...
Estaba usando un instalador estándar iniciado al hacer doble clic en el Finder. Determiné que el proceso que estaba atascado estaba rm -iutilizando pspara ver la línea de comando y solucioné el problema eliminando el rmalias. YMMV
Luego, el instalador estaba ejecutando un shell interactivo y, por lo tanto, estaba seriamente dañado. Un instalador roto no es motivo suficiente para desaconsejar los alias de shell en general. YMMV
Sin embargo, es un buen consejo no crear un alias para el rmcomando, como dijo morgant, porque se sentirá cómodo con rmno eliminar archivos y luego podría eliminar accidentalmente algo en un sistema donde no se ha agregado dicho alias. Además, mover un archivo a la papelera no es tan simple como simplemente mv {} ~/.Trash. Si el archivo está en un volumen separado, por ejemplo, esto copiará el archivo a su directorio de inicio y eliminará el original.
También uso esta función corta en mi .bashrc; sin embargo, debe realizar este cambio para function trash { mv "$@" ~/.Trash ; }evitar que se rompa en los nombres de las carpetas con espacios.

Simplemente he puesto este script

#!/bin/bash
application=$(basename "$0")
if [ "$#" == 0 ]; then
    echo "Usage: $application path [paths...]"
    exit 1
fi
trashdir="/Users/${USER}/.Trash"
while (( "$#" )); do
    if [ -e "$1" ]; then
        src=$(basename "$1")
        dst=$src
        while [ -e "$trashdir/$dst" ]; do
            dst=$src+`date +%H-%M-%S`
        done
        mv -f "$1" "$trashdir/$dst"
    else
        echo "$1" does not exist.
    fi
    shift
done

in ~/bin/trash, lo hizo ejecutable chmod +x ~/bin/trashy agregó la siguiente línea a~/.bash_profile

PATH=$PATH:$HOME/bin

Entonces uno puede usarlo como

$ trash broken.js olddir cleanup.*

Una función simple podría permitirle eliminar archivos moviéndolos a la carpeta .Trash del usuario:

trash() {
   mv $1 ~/.Trash
}
? ¿Por qué un voto negativo? este seria mi pensamiento tambien..
Probablemente necesite $*en lugar de $1, pero terminaría con la misma respuesta que mv "$@" ~/.Trash. Por qué la gente lo vota negativamente, verifique los comentarios de la otra respuesta.
Tenga cuidado con este alias; esto funciona si solo tiene una partición o unidad. Si está trabajando en un segundo volumen o recurso compartido de red, esto realmente copiará el archivo a la papelera de su directorio de inicio, ¡lo que probablemente no sea lo que quería hacer!