Как переместить файлы в корзину из командной строки?

129

Я много работаю на терминале, и сегодня имел опыт набора текста

rm fileInQuestion.txt

Прежде чем выяснить, что мне действительно нужно файл fileInQuestion.txt. Если бы я удалил в GUI, я бы просто вытащил его из корзины. Я хотел бы знать, возможно ли перегрузить 'rm' в Терминале таким образом, чтобы он отправлял файл / файлы в корзину при выходе.

Джо
источник
1
Существуют программы, которые могут восстанавливать удаленные файлы (если эти сектора на жестком диске не перезаписываются в это время!). Когда это происходит, вы должны использовать один из этих ...
iconoclast
Также см. Askubuntu.com/q/468721/250556 для googlers, ищущих очистку файлов ubuntu / debian / linux.
ThorSummoner

Ответы:

100

Я бы не советовал ступенчатость , rmчтобы , mvкак вы могли бы получить в привычку rmпостоянно не удаляя файлы , а затем столкнуться с проблемами на других компьютерах или в рамках других учетных записей пользователей , когда он делает постоянно удалять.

Я написал набор bashскриптов , которые добавляют больше Mac OS X инструменты типа командной строки (в дополнение к ряду встроенных в них , как open, pbcopy, pbpasteи т.д.), что самое главное trash. Моя версия trashбудет делать все правильно, что псевдоним rmне будет (и, надеюсь, ничего плохого, но я уже несколько лет использую его на своих компьютерах Mac без потери данных), включая: переименование файла, как это делает Finder если файл с таким именем уже существует, поместите файлы в нужную папку «Корзина» на внешние тома; у него также есть некоторые добавленные тонкости, такие как: он пытается использовать AppleScript, когда он доступен, чтобы вы получили хороший звук мусора и тому подобное (но не требует его, так что вы все равно можете использовать его через SSH, когда ни один пользователь не вошел в систему), он может дать вам размер мусора во всех томах.

Вы можете взять мой пакет tools-osx с моего сайта или самую последнюю и лучшую версию из репозитория GitHub .

Там также команда , разработанная Али Rantakari , но я не проверял , что один сам.trash

morgant
источник
4
Отличный ответ, намного лучше моего!
user1256923
24
Я использовал trashRantakari довольно долгое время и могу за это поручиться. Он компилируется в Objective-C и ловко использует стандартные API-интерфейсы файловой системы и, в случае сбоя (т. Е. У пользователя нет достаточных прав), вызывает Finder для удаления файлов (фактически запрашивая аутентификацию). Вы можете прочитать более подробную информацию о trashот hasseg.org/blog .
Яри ​​Кейнянен
26
Корзина также доступна через менеджер пакетов brew. просто использовать: brew install trash.
Лэндон Кун
8
@ landon9720 Хороший вопрос. И, чтобы уточнить для других, trashкоманда, доступная через Homebrew, является командой Алая Рантакари (см. brewФормулу ).
Моргант
3
Я смог исправить ошибку, запустив brew remove trashи затем brew install trash.
Элиас Замария
99

Инструмент командной строки для мусора может быть установлен через brew install trash.

Это позволяет вам восстанавливать файлы с помощью командной строки или Finder.

Пол Венцель
источник
2
Какое элегантное решение!
Мистер Пей,
6
Также доступно в macports:port install trash
Holocronweaver
каждый раз, когда я пытаюсь brew install trash, я получаю это: pastebin.com/N92cM7d8
Бен Легжеро
@ BenC.R.Leggiero Я хотел бы перенести этот вопрос на github.com/ali-rantakari/trash/issues . Ты brew updateпервый? Хорошо работает с моей стороны.
Пол Венцель
@PaulWenzel да, и, кажется, обновляется просто отлично. Я отправлю вопрос.
Бен Легжеро
21

У меня есть исполняемый файл, вызванный remгде-то в моем $PATHсо следующим содержанием:

РЕДАКТИРОВАТЬ: приведенный ниже код является пересмотренной и улучшенной версией в сотрудничестве с Дейвом Абрахамсом :

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

Он ведет себя точно так же, как удаление из Finder. (Смотрите сообщение в блоге здесь .)

Энтони Смит
источник
4
Это должно иметь больше очков IMO. Поскольку это AppleScript, он использует фактический процесс мусора, чтобы переместить файл в корзину, что означает, что он будет вести себя точно так же. Позор однострочник не был обеспечен однако.
mxcl
2
Этот ответ является наглядным уроком о том, как все делать правильно. Он работает с подстановочными знаками оболочки и работает через Finder. Он не изобретает никаких колес, и это настолько просто, насколько это возможно. Я поместил его в свой ~/bin, назвал его trash, и он сработал в первый раз, что позволило мне более эффективно уничтожать множество файлов, чем если бы мне приходилось нажимать на них в окнах Finder. Большая благодарность Я надеюсь, что вы отправите больше ответов!
Бен Ковиц
3
Эта версия обрабатывает кавычки. Это немного меняет поведение при обработке ошибок, которое в вышеприведенной версии выглядит не очень тщательно отработанным (ошибки в stdout вместо stderr, нет кода выхода), но ошибка, которую вы получаете, osascriptкогда файл не существует не красиво, так что вы можете настроить эту часть.
Дэйв Абрахамс
3
Хорошая работа. Эта версия включает эти изменения, а также (1) пытается rmмаксимально имитировать команду оболочки с точки зрения отображения сообщений, когда файлы не существуют, и (2) объединяет все в один osascriptвызов.
Энтони Смит
3
Один удар
Дейв Абрахамс
4

Я нашел довольно хороший код, который можно добавить в конце профиля пакета пользователя и заставлять rmперемещать файлы в корзину каждый раз, когда он запускается.

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
}

источник: http://hints.macworld.com/article.php?story=20080224175659423

rraallvv
источник
2
Это очень умно, но я все равно не рекомендовал бы это. Это умно, потому что он находится в профиле bash для пользователя, и поэтому только пользователь может выполнить эту версию функции, введя ее, сценарии, которые полагаются на rm, по-прежнему будут вызывать оригинал. Но я бы не рекомендовал делать это, потому что пользователь привыкнет к rm, действующему таким образом, когда это не происходит на других машинах. Я собираюсь использовать это, но переименовать функцию «мусор»
Мэтт Паркинс
Я использую ту же функцию с двумя изменениями: ① Я исправил ошибку в функции, которая приводила к тому, что любая папка переименовывалась в отметку времени, если она была завершена с помощью табуляции и включает в себя завершающий слеш: для этого требуются следующие изменения: замена Строка local dst=${path##*/}с local dst=${mindtrailingslash##*/}и вставка другой строки непосредственно перед той, которая говорит local mindtrailingslash=${path%/}. Use Я использую имя function rr. Таким образом, он не мешает обычному rm, но имя также короткое и быстрое для ввода ( подойдет любое другое имя).
маш
Измените имя rm()на rmt()- Таким образом, вы все равно можете использовать rmкоманду, когда захотите. Я думаю о rmt в моей голове как remove to trash: D
James111
4

Используйте команду терминала osascript, интерпретатор AppleScript.

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

Это говорит AppleScript сказать Finder отправлять файл в корзину.

PWD необходим для относительных путей к файлам, так как AppleScript плохо справляется с этим.

CDE
источник
1
Просто, эффективно и не нужно ничего устанавливать! Приятно.
SilverWolf
2

современный подход с использованием 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)
}
SLF
источник
1
Хотя эта ссылка может ответить на вопрос, лучше включить сюда основные части ответа и предоставить ссылку для справки. Ответы, содержащие только ссылки, могут стать недействительными, если связанная страница изменится.
Джерран
@jherran спасибо за напоминание, я добавил сегмент кода
slf
Это мой предпочтительный ответ, потому что он использует ту же логику и API, что и GUI.
Джейсон Р. Кумбс
1
Теперь, если бы только была версия Python, которая избавляла от необходимости бинарного файла объемом 3 МБ для выполнения одного системного вызова.
Джейсон Р. Кумбс
1

Хотя можно rmперемещать файлы в корзину вместо их удаления, я бы не советовал переносить образ мыслей безопасности графических пользовательских интерфейсов в оболочку UNIX. Есть много способов нанести серьезный ущерб с помощью терминала. Лучший совет IMHO - просто дважды подумать, прежде чем нажимать enterклавишу в окне оболочки.

Если вы хотите rmнапомнить, что собираетесь удалить файл, используйте следующий псевдоним (для /bin/bashвставки этой строки .bashrcв ваш домашний каталог):

alias rm "rm -i"

Это сделает rmзапрос подтверждения, прежде чем пытаться удалить каждый файл.

Если у вас работает TimeMachine (я надеюсь, что это так!), Вы всегда можете получить файл из резервной копии. Таким образом, вы можете потерять максимум один час работы. Что достаточно плохо, конечно. Поэтому подумайте еще раз, прежде чем нажимать эту enterклавишу!

Маки Мессер
источник
1
Не делай этого! Установочные скрипты могут использовать rmи зависать с псевдонимом rm -i.
Old Pro
3
@OldPro: .bashrcвыполняется только в том случае, если оболочка является интерактивной. Проверьте справочную страницу !
Маки Мессер
я бы посоветовал не удалять защитные сетки или не советовать другим делать это.
the0ther
Я пойду против скептиков и скажу, что я использую этот трюк с большим эффектом, но это определенно должно быть сделано только зная ловушки. Два не упоминаются, это то, что он тренирует ваш мозг, который rmбезопаснее, чем он, что приведет к проблемам в других системах. Также, если вы используете -f, -iполностью игнорируется. Тем не менее, это хорошая сеть безопасности. Лучше один, чтобы никогда не использовать rmв пользу rmiпсевдонима ( alias rmi="rm -i") или отличной trashутилиты. Кроме того, я добавлю, что все должны были положить [ -f ~/.bashrc ] && source ~/.bashrcих .bash_profileсейчас.
mattmc3
1

С помощью Homebrew можно установить две утилиты, которые могут это сделать:

  1. мусор

    Это небольшая программа командной строки для OS X, которая перемещает файлы или папки в корзину. USP этой команды позволяет легко восстанавливать файлы. Команда для удаления файлов / папок бесполезна, если вы не можете восстановить файлы / папки после их удаления. С веб-сайта команды:

По умолчанию, корзина просит Finder переместить указанные файлы / папки в корзину, а не вызывать системный API, чтобы сделать это из-за функции «положить обратно», которая работает только при очистке файлов через Finder.


-F

Попросите Finder переместить файлы в корзину, а не использовать системный API. Это медленнее, но использует пользовательский интерфейс Finder (например, звуки) и обеспечивает работу функции «возврата».

-l

Список элементов, находящихся в данный момент в корзине. Если используется этот аргумент, файлы указывать не нужно.

-e

Очистить корзину. корзина запрашивает подтверждение перед выполнением этого действия. Если используется этот аргумент, файлы указывать не нужно.

Для установки trashзапустите следующее в Терминале:

brew install trash,


  1. rmtrash

    Инструмент командной строки, который перемещает файлы в корзину. Со справочной страницы команды:

Эта команда перемещает файлы в корзину, а не полностью удаляет их из файловой системы. Очень полезно, если вы решите, что хотите этот файл в конце концов ...


-u ИМЯ ПОЛЬЗОВАТЕЛЯ

необязательный аргумент. Это переместит файл в корзину указанного пользователя. Обратите внимание, что для этого вам необходимы достаточные привилегии.

Для установки rmtrashзапустите следующее в Терминале:

brew install rmtrash,

Нимеш Нима
источник
1

Вот довольно простое однострочное решение для добавления в ваш профиль bash. Обратите внимание, что он уже перезапишет что-то с таким же именем в корзине.

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

Использование:

 ~/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 $$$
Райан Так
источник
отредактировал соответственно - спасибо за вклад!
Райан Так
0

Правильно уничтожить вещи (так что это определенно можно восстановить) сложнее, чем просто mvк ~/.Trash.

osx-trash может быть тем, что вы ищете. ( Будьте бдительны - я не пробовал и не могу подтвердить, насколько это безопасно.)

шухер
источник
0

Проверьте trash-cli. Он работает кроссплатформенный, без мусора и поддерживает Put Back.

Вы можете установить его с помощью (требуется Node.js ) :

$ npm install --global trash-cli

Кроме того, если вы не хотите использовать Node.js, вы можете установить собственный двоичный файл osx-trashвручную.

Синдре Сорхус
источник
-1

В вашем .bashrc (или там, где вы храните параметры для вашей оболочки), попробуйте добавить псевдоним, который изменяет поведение rm для перемещения материала в ~ / .Trash, как в:

alias rm='move/to/.Trash'

Хотя этот псевдоним далеко не тривиален для реализации (по крайней мере, для меня), потому что использование mv (основной кандидат на эту работу)

mv file where

поэтому наличие псевдонима, который помещает часть 'where' перед перемещаемым файлом, может быть довольно схематичным. Я рассмотрю это, возможно, получу более существенный совет.

РЕДАКТИРОВАТЬ: Я просто попытался добавить следующее в мой .bashrc, и это работает:

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

Это гораздо более примитивно, чем другие предложения, но вы избегаете установки новых вещей.

user1256923
источник
3
Псевдоним rmк чему-либо опасен, потому что он может сломать установочные скрипты. Я узнал об этом на собственном горьком опыте , когда я псевдонимами , rmчтобы rm -iи имел Установок повесить.
Old Pro
@ Old Pro, это псевдоним, который я использую для rm на всех своих компьютерах, начиная с дня 0, и у меня никогда не было проблем из-за этого. Хотите привести пример?
user1256923
3
@OldPro: .bashrcиспользуется только для интерактивных оболочек. Если вы запускаете ./install.shновый процесс запускается, и псевдоним не будет активным. Однако, если вы запустите . install.shваш текущий процесс, он запустит установщик, и псевдоним активен. RTFM ...
Маки Мессер
3
Затем установщик запустил интерактивную оболочку и поэтому был серьезно сломан. Один сломанный установщик вряд ли является достаточной причиной для советов против псевдонимов оболочки в целом. YMMV
Mackie Messer
1
Тем не менее, это хороший совет , чтобы не псевдоним rmкоманды, как сказал morgant, потому что вы освоите rmфактически не удаляя файлы , а затем может случайно удалить что - то в системе , где не было добавлено никакой такой псевдоним. Кроме того, перемещение файла в корзину не так просто, как просто mv {} ~/.Trash. Например, если файл находится на отдельном томе, он скопирует файл в ваш домашний каталог и удалит оригинал.
Джош
-1

Я просто поставил этот скрипт

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

в ~/bin/trash, сделал его извиняемым chmod +x ~/bin/trash, и добавил следующую строку~/.bash_profile

PATH=$PATH:$HOME/bin

Тогда можно использовать его как

$ trash broken.js olddir cleanup.*
JP
источник
-2

Простая функция может позволить вам удалять файлы, перемещая их в пользовательскую папку .Trash:

trash() {
   mv $1 ~/.Trash
}
james.kobol
источник
? почему отрицательный голос? это было бы моей мыслью также ..
CousinCocaine
Вам, вероятно, нужно $*вместо $1, но тогда вы получите тот же ответ, что и mv "$@" ~/.Trash. Почему люди голосуют отрицательно, проверьте комментарии другого ответа.
Кенорб
Будьте осторожны с этим псевдонимом; это работает, если у вас есть только один раздел или диск. Если вы работаете со вторым томом или сетевым ресурсом, это фактически скопирует файл в корзину вашего домашнего каталога, что, вероятно, не то, что вы хотели сделать!
JMK