Jak przenieść pliki do kosza z wiersza poleceń?

128

Wykonuję wiele prac terminalowych, a dziś miałem doświadczenie w pisaniu

rm fileInQuestion.txt

Zanim dowiedziałem się, że naprawdę potrzebowałem fileInQuestion.txt. Gdybym usunął go z GUI, właśnie wyciągnąłbym go z Kosza. Chciałbym wiedzieć, czy możliwe jest przeciążenie „rm” w terminalu w taki sposób, że wysyła plik / pliki do Kosza po wyjściu.

Joe
źródło
1
Istnieją programy, które mogą odzyskać usunięte pliki (o ile te sektory na dysku twardym nie zostaną w międzyczasie nadpisane!). Kiedy tak się stanie, powinieneś użyć jednego z tych ...
iconoclast
Zobacz także askubuntu.com/q/468721/250556 dla googlerów poszukujących śmieci do plików ubuntu / debian / linux.
ThorSummoner,

Odpowiedzi:

100

Nie radzę aliasing rmdo mvjak można dostać w zwyczaju rmplików nie trwałe usunięcie, a następnie uruchomić do problemów na innych komputerach lub na podstawie innych kont użytkowników, jeśli nie na stałe usunąć.

Napisałem zestaw bashskryptów dodać więcej narzędzi Mac OS X jak wiersz poleceń (oprócz szeregu wbudowanych w nich jak open, pbcopy, pbpaste, itd.), Co najważniejsze trash. Moja wersja trashzrobi wszystkie prawidłowe rzeczy, których aliasing rmnie zrobi (i mam nadzieję, że nic złego, ale używam go na moich komputerach Mac od kilku lat bez żadnych utraconych danych), w tym: zmiana nazwy pliku tak, jak robi to Finder jeśli plik o tej samej nazwie już istnieje, umieszczanie plików w odpowiednim folderze Kosz na woluminach zewnętrznych; ma również pewne dodatkowe zalety, takie jak: próbuje użyć AppleScript, gdy jest dostępny, aby uzyskać przyjemny dźwięk śmieci i tak dalej (ale nie wymaga go, więc możesz go używać przez SSH, gdy żaden użytkownik nie jest zalogowany), może daje rozmiar kosza we wszystkich woluminach.

Możesz pobrać mój zestaw narzędzi-osx z mojej witryny lub najnowszą i najlepszą wersję z repozytorium GitHub .

Jest też poleceń opracowany przez Ali Rantakari , ale nie testowałem, że jeden siebie.trash

morgant
źródło
4
Doskonała odpowiedź, znacznie lepsza niż moja!
użytkownik1256923
24
Używam trashprzez Rantakari od dłuższego czasu i naprawdę mogę za to ręczyć. Jest skompilowany w Objective-C i sprytnie wykorzystuje standardowe interfejsy API systemu plików, a jeśli zawiedzie (tzn. Użytkownik nie będzie miał wystarczających uprawnień), wywołuje Findera w celu usunięcia plików (skuteczne monitowanie o uwierzytelnienie). Możesz przeczytać więcej informacji o trashod hasseg.org/blog .
Jari Keinänen
26
Kosz jest również dostępny za pośrednictwem menedżera pakietów parzenia. wystarczy użyć: brew install trash.
Landon Kuhn
8
@ landon9720 Dobry punkt. Aby wyjaśnić innym, trashpolecenie dostępne przez Homebrew należy do Alai Rantakari (patrz brewwzór ).
morgant
3
Byłem w stanie naprawić błąd, uruchamiając, brew remove trasha następnie brew install trash.
Elias Zamaria,
98

Śmieci narzędzie wiersza polecenia można zainstalować poprzez brew install trash.

Pozwala przywrócić pliki zepsute za pomocą wiersza polecenia lub Findera.

Paul Wenzel
źródło
2
Cóż za eleganckie rozwiązanie!
Pan Pei
6
Dostępne również w Macports:port install trash
holocronweaver
za każdym razem, gdy próbuję brew install trash, dostaję to: pastebin.com/N92cM7d8
Ben Leggiero
@ BenC.R.Leggiero Chciałbym przenieść tę kwestię na github.com/ali-rantakari/trash/issues . Czy ty brew updatepierwszy Działa dobrze na moim końcu.
Paul Wenzel,
@PaulWenzel tak, i wydaje się aktualizować w porządku. Wyślę problem.
Ben Leggiero,
21

Mam plik wykonywalny wywołany remgdzieś w mojej $PATHz następującą zawartością:

EDYCJA: poniższy kod to poprawiona i ulepszona wersja we współpracy z Dave'em Abrahamsem :

#!/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

Zachowuje się dokładnie tak samo, jak usuwanie z Findera. (Zobacz post na blogu tutaj .)

Anthony Smith
źródło
4
To powinno mieć więcej punktów IMO. Ponieważ jest to AppleScript, używa rzeczywistego procesu kosza do przeniesienia pliku do kosza, co oznacza, że ​​zachowa się dokładnie tak samo. Szkoda, że ​​jedna linijka nie została jednak zapewniona.
mxcl
2
Ta odpowiedź jest lekcją obiektową, jak zrobić wszystko dobrze. Działa z symbolami wieloznacznymi powłoki i działa przez Findera. Nie wymyśla na nowo żadnych kół i jest tak proste, jak to tylko możliwe. Umieściłem go w swoim ~/bin, nadałem mu nazwę trash, i zadziałało po raz pierwszy - umożliwiając mi usuwanie wielu plików znacznie wydajniej niż gdybym musiał je klikać w oknach Findera. Ogromna wdzięczność. Mam nadzieję, że opublikujesz więcej odpowiedzi!
Ben Kovitz,
3
Ta wersja obsługuje cytaty. Zmienia to nieco zachowanie obsługi błędów, które w powyższej wersji wydaje się niezbyt starannie opracowane (błędy standardowego wyjścia zamiast standardowego, brak kodu wyjścia), ale błąd, który osascriptpojawia się, gdy plik nie istnieje nie jest piękny, więc możesz dostroić tę część.
Dave Abrahams,
3
Dobra robota. Ta wersja zawiera te zmiany, a także (1) próbuje naśladować komendę powłoki w rmjak największym stopniu pod względem wyświetlania komunikatów, gdy pliki nie istnieją, i (2) zestawia wszystko w jedno osascriptwywołanie.
Anthony Smith
3
One- upping
Dave Abrahams
4

Znalazłem całkiem niezły kod, który można dodać na końcu profilu wsadowego użytkownika i powoduje rmprzenoszenie plików do kosza przy każdym uruchomieniu.

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
}

źródło: http://hints.macworld.com/article.php?story=20080224175659423

rraallvv
źródło
2
To jest v sprytne, ale nadal nie poleciłbym tego. Jest sprytny, ponieważ znajduje się w profilu bash dla użytkownika, więc tylko użytkownik może wykonać tę wersję funkcji, wpisując ją, skrypty korzystające z rm nadal będą wywoływać oryginał. Ale nie poleciłbym tego robić, ponieważ użytkownik przyzwyczai się do rm działającego w ten sposób, gdy nie działa na innych komputerach. Użyję tego, ale zmienię nazwę funkcji „kosz”
Matt Parkins
Korzystam z tej samej funkcji z dwiema zmianami: ① Poprawiłem błąd w funkcji, który powoduje zmianę nazwy dowolnego folderu na znacznik czasu, jeśli został uzupełniony tabulatorami o wstawianie ukośnika: Wymaga to następujących zmian: Zastąpienie linia local dst=${path##*/}z local dst=${mindtrailingslash##*/}i wkładając kolejną linię tuż przed tym, który mówi local mindtrailingslash=${path%/}. Use Używam nazwy function rr. W ten sposób nie ingeruje w zwykły rm, ale nazwa jest podobnie krótka i szybka do wpisania (zrobiłaby to każda inna nazwa).
mach
Zmień nazwę rm()na rmt()- W ten sposób możesz nadal używać rmpolecenia, kiedy chcesz. Myślę o rmt w mojej głowie jako remove to trash: D
James111
4

Użyj komendy terminalowej osascript, interpretera AppleScript.

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

Mówi to AppleScript, aby powiedział Finderowi, aby wysłał plik do kosza.

PWD jest potrzebne do względnych ścieżek plików, ponieważ AppleScript nie radzi sobie tak dobrze.

cde
źródło
1
Prosty, skuteczny i nie trzeba niczego instalować! Miły.
SilverWolf
2

nowoczesne podejście przy użyciu szybkiego

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)
}
slf
źródło
1
Chociaż ten link może odpowiedzieć na pytanie, lepiej jest dołączyć tutaj istotne części odpowiedzi i podać link w celach informacyjnych. Odpowiedzi zawierające tylko łącze mogą stać się nieprawidłowe, jeśli połączona strona ulegnie zmianie.
jherran
@herherran dzięki za przypomnienie, dodałem segment kodu
slf
To moja preferowana odpowiedź, ponieważ używa tej samej podstawowej logiki i interfejsów API co GUI.
Jason R. Coombs
1
Teraz, gdyby tylko istniała wersja Pythona, która pozwalała uniknąć konieczności użycia pliku binarnego o wielkości 3 MB do wykonania jednego wywołania systemowego.
Jason R. Coombs
1

Chociaż możliwe jest rmprzenoszenie plików do Kosza zamiast ich usuwania, odradzam przenoszenie sposobu myślenia o sieci bezpieczeństwa graficznych interfejsów użytkownika do powłoki UNIX. Istnieje wiele sposobów wyrządzenia poważnych szkód za pomocą terminala. Najlepszą radą IMHO jest po prostu zastanowienie się dwa razy przed naciśnięciem enterklawisza w oknie powłoki.

Jeśli chcesz rmprzypomnieć, że masz zamiar usunąć plik, rozważ użycie następującego aliasu (aby /bin/bashumieścić tę linię w .bashrckatalogu domowym):

alias rm "rm -i"

Spowoduje to rmpotwierdzenie żądania przed próbą usunięcia każdego pliku.

Jeśli masz uruchomiony TimeMachine (mam nadzieję, że tak!), Zawsze możesz pobrać plik z kopii zapasowej. W ten sposób możesz stracić najwyżej godzinę pracy. Co oczywiście jest wystarczająco złe. Pomyśl jeszcze raz przed naciśnięciem tego enterklawisza!

Mackie Messer
źródło
1
Nie rób tego! Skrypty instalatora mogą używać rmi zawieszać się z aliasem rm -i.
Old Pro
3
@OldPro: .bashrcjest wykonywany tylko wtedy, gdy powłoka jest interaktywna. Sprawdź stronę podręcznika man !
Mackie Messer
odradzałbym usuwanie siatek bezpieczeństwa lub zachęcanie innych do tego.
the0ther
Sprzeciwiam się niegodziwcom i mówię, że używam tej sztuczki z wielkim skutkiem, ale zdecydowanie należy to zrobić, znając pułapki. Dwie nie wymienione to to, że ćwiczy twój mózg, który rmjest bezpieczniejszy niż to, co wpędzi cię w kłopoty w innych systemach. Ponadto, jeśli używasz -f, -ijest całkowicie ignorowany. To powiedziawszy, to dobra siatka bezpieczeństwa. Lepszym rozwiązaniem jest nigdy nie używać rmna rzecz rmialiasu ( alias rmi="rm -i") lub doskonałej trashużyteczności. Dodam też, że wszyscy powinni już dołożyć [ -f ~/.bashrc ] && source ~/.bashrcswoje .bash_profile.
mattmc3
1

Istnieją dwa narzędzia, które można zainstalować za pośrednictwem Homebrew, które mogą to osiągnąć:

  1. śmieci

    Jest to mały program wiersza polecenia dla systemu OS X, który przenosi pliki lub foldery do kosza. USP tego polecenia umożliwia łatwe przywracanie plików. Polecenie kosza plików / folderów nie jest przydatne, jeśli nie można przywrócić plików / folderów po ich skasowaniu. Ze strony internetowej polecenia:

Domyślnie kosz prosi Findera o przeniesienie określonych plików / folderów do kosza zamiast wywoływania systemowego interfejsu API w tym celu ze względu na funkcję „odłóż”, która działa tylko podczas usuwania plików za pomocą Findera.


-FA

Poproś Findera o przeniesienie plików do kosza zamiast korzystania z systemowego interfejsu API. Jest to wolniejsze, ale wykorzystuje interfejs użytkownika Findera (np. Dźwięki) i zapewnia, że ​​funkcja „odłóż” działa.

-l

Wyświetl elementy znajdujące się obecnie w koszu. Jeśli użyty zostanie ten argument, nie trzeba podawać żadnych plików.

-mi

Wynieś śmieci. Kosz prosi o potwierdzenie przed wykonaniem tej akcji. Jeśli użyty zostanie ten argument, nie trzeba podawać żadnych plików.

Aby zainstalować, trashuruchom następujące polecenie w terminalu:

brew install trash.


  1. rmtrash

    Narzędzie wiersza polecenia, które przenosi pliki do kosza. Na stronie man polecenia:

To polecenie przenosi pliki do kosza, zamiast całkowicie usuwać je z systemu plików. Bardzo przydatne, jeśli mimo wszystko zdecydujesz, że chcesz ten plik ...


-u NAZWA UŻYTKOWNIKA

opcjonalny argument. Spowoduje to przeniesienie pliku do kosza określonego użytkownika. Pamiętaj, że potrzebujesz wystarczających uprawnień, aby to osiągnąć.

Aby zainstalować, rmtrashuruchom następujące polecenie w terminalu:

brew install rmtrash.

Nimesh Neema
źródło
1

Oto dość trywialne jedno-liniowe rozwiązanie, które można dodać do swojego profilu bash. Pamiętaj, że spowoduje to nadpisanie czegoś o tej samej nazwie w koszu.

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

Stosowanie:

 ~/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 $$$
Ryan Tuck
źródło
odpowiednio zmodyfikowałem - dziękuję za wkład!
Ryan Tuck
0

Prawidłowo koszu rzeczy (tak, to na pewno do odzyskania) jest trudniejsze niż po prostu mvdo ~/.Trash.

osx-trash może być tym, czego szukasz. ( Zastrzegający emptor - jeszcze go nie próbowałem i nie mogę ręczyć za jego bezpieczeństwo).

Nic
źródło
0

Sprawdź trash-cli. Działa na wielu platformach, nie ma dźwięku śmieci i obsługuje funkcję Put Back.

Możesz go zainstalować za pomocą (wymaga Node.js ) :

$ npm install --global trash-cli

Alternatywnie, jeśli nie chcesz używać Node.js, możesz osx-trashręcznie zainstalować natywny plik binarny .

Sindre Sorhus
źródło
-1

W swoim .bashrc (lub gdziekolwiek trzymasz parametry swojej powłoki), spróbuj dodać alias, który zmienia zachowanie rm na przenoszenie rzeczy do ~ / .Trash, jak w:

alias rm='move/to/.Trash'

Ten alias jest daleki od implementacji (przynajmniej dla mnie), ponieważ użycie mv (głównego kandydata do użycia w tym zadaniu) jest

mv file where

więc posiadanie aliasu, który umieszcza część „gdzie” przed przenoszonym plikiem, może być dość szkicowe. Przyjrzę się temu i mogę uzyskać bardziej merytoryczną poradę.

EDYCJA: Właśnie próbowałem dodać następujące do mojego .bashrc i działa:

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

Jest znacznie bardziej prymitywny niż inne sugestie, ale unikasz instalowania nowych rzeczy.

użytkownik1256923
źródło
3
Aliasing rmz czymkolwiek jest niebezpieczny, ponieważ może uszkodzić skrypty instalatora. Nauczyłem się tego na własnej skórze, kiedy aliasem rmdo rm -ii miał instaluje powiesić.
Old Pro
@Old Pro, to jest alias, którego używam dla rm na wszystkich moich komputerach, od 0 i nigdy nie miałem z tego powodu problemów. Chcesz podać przykład?
użytkownik1256923
3
@OldPro: .bashrcsłuży tylko do interaktywnych powłok. Jeśli uruchomisz ./install.shnowy proces, zostanie uruchomiony i alias nie będzie aktywny. Jeśli jednak uruchomisz . install.shbieżący proces, uruchomi się instalator, a alias jest aktywny. RTFM ...
Mackie Messer,
3
Następnie instalator uruchomił interaktywną powłokę i dlatego został poważnie uszkodzony. Jeden zepsuty instalator nie jest wystarczającym powodem, aby odradzać aliasy powłoki w ogóle. YMMV
Mackie Messer
1
Jednak to jest dobra rada, aby nie aliasu do rmpolecenia, jak morgant powiedział, bo będziesz się komfortowo rmw rzeczywistości nie usuwanie plików, a następnie może przypadkowo usunąć coś w systemie, w którym nie ma takiego alias został dodany. Przeniesienie pliku do kosza nie jest tak proste jak tylko mv {} ~/.Trash. Jeśli na przykład plik znajduje się na osobnym woluminie, skopiuje go do katalogu domowego i usunie oryginał.
Josh
-1

Po prostu umieściłem ten skrypt

#!/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, uczynił go możliwym do wyliczenia chmod +x ~/bin/trashi dodał następujący wiersz do~/.bash_profile

PATH=$PATH:$HOME/bin

Następnie można go użyć jako

$ trash broken.js olddir cleanup.*
JP
źródło
-2

Prosta funkcja może pozwolić ci na usunięcie plików poprzez przeniesienie ich do folderu .Trash użytkownika:

trash() {
   mv $1 ~/.Trash
}
james.kobol
źródło
? dlaczego głosowanie negatywne? taka też byłaby moja myśl.
CousinCocaine
Prawdopodobnie potrzebujesz $*zamiast $1, ale wtedy uzyskasz taką samą odpowiedź jak mv "$@" ~/.Trash. Dlaczego ludzie głosują to negatywnie, sprawdź komentarze z drugiej odpowiedzi.
kenorb
Uważaj na ten alias; działa to, jeśli masz tylko jedną partycję lub dysk. Jeśli pracujesz nad drugim woluminem lub udziałem sieciowym, spowoduje to skopiowanie pliku do kosza katalogu domowego, co prawdopodobnie nie jest tym, co chciałeś zrobić!
jmk