Làm cho `rm` di chuyển vào thùng rác


54

Có tập lệnh / ứng dụng Linux nào, thay vì xóa các tập tin, di chuyển chúng đến một vị trí thùng rác đặc biệt trên thùng rác? Tôi muốn điều này như một sự thay thế cho rm(thậm chí có thể là bí danh sau này; có những ưu và nhược điểm cho điều đó).

Theo thùng rác, tôi có nghĩa là một thư mục đặc biệt. Một bước duy nhất mv $* ~/.trashlà một bước đầu tiên, nhưng lý tưởng là điều này cũng sẽ xử lý việc dọn rác một số tệp cùng tên mà không ghi đè lên các tệp bị hỏng cũ hơn và cho phép khôi phục các tệp về vị trí ban đầu của chúng bằng một lệnh đơn giản (một loại hình hoàn tác ngược lại). Hơn nữa, thật tuyệt nếu thùng rác được tự động dọn sạch khi khởi động lại (hoặc một cơ chế tương tự để ngăn chặn sự tăng trưởng vô tận).

Các giải pháp một phần cho điều này tồn tại, nhưng hành động phục hồi của Hồi giáo nói riêng không phải là chuyện nhỏ. Có bất kỳ giải pháp hiện có nào cho việc này không dựa vào hệ thống rác từ vỏ đồ họa không?

(Bên cạnh đó, đã có những cuộc thảo luận bất tận cho dù cách tiếp cận này có hợp lý hay không, thay vì sử dụng các bản sao lưu và VCS thường xuyên. Trong khi những cuộc thảo luận đó có một điểm, tôi tin rằng vẫn còn một yêu cầu thích hợp cho yêu cầu của tôi.)


4
Điều này có thể liên quan đến câu hỏi SuperUser Hai lệnh để di chuyển tệp vào thùng rác. Có gì khác biệt? . Tôi đã từng sử dụng gvfs-trashtrước đây, nhưng chưa bao giờ có nhu cầu khôi phục từ dòng lệnh cho đến khi bạn khơi dậy sự tò mò của tôi. Câu trả lời cho câu hỏi liên kết có thể giúp đỡ.
ephsmith

1
@ephsmith Cảm ơn, liên kết tốt. Vấn đề với những cách tiếp cận đó là chúng bị ràng buộc với vỏ máy tính để bàn cụ thể (thuật ngữ chính xác ở đây là gì?), Một điều mà tôi muốn tránh.
Konrad Rudolph

1
Là di chuyển các tập tin từ bất kỳ hệ thống tập tin để ~ cố ý của bạn? Bởi vì một ngày nào đó bạn có thể xóa một hình ảnh iso 4GB nằm trên một thư mục được gắn với sshfs từ một máy chủ thực sự từ xa.
Mischa Arefiev

1
@Mischa Thành thật mà nói, tôi đã không nghĩ nhiều về nó. Điều đó nói rằng, nó nên hoạt động với các quyền của người dùng thông thường, vì vậy mục tiêu cần phải là một vị trí có thể ghi và không cần quá nhiều cấu hình.
Konrad Rudolph

3
Làm bất cứ điều gì bạn muốn, chẳng hạn như các giải pháp được nêu trong các câu trả lời dưới đây, nhưng đừng đặt tên cho nó là rm. Như những người khác đã chỉ ra, việc đổi tên / tái sử dụng các lệnh tiêu chuẩn khiến bạn dễ bị tổn thương khi bạn thường xuyên sử dụng chúng trên các hệ thống khác, nhưng nó cũng sẽ gây ra sự cố cho bất kỳ ai khác (có thể hỗ trợ bạn) khi sử dụng hệ thống / tài khoản của bạn khi có kết quả không mong muốn.
Joe

Câu trả lời:


37

Có một đặc điểm kỹ thuật (bản nháp) cho Thùng rác trên freedesktop.org. Nó rõ ràng là những gì thường được thực hiện bởi môi trường máy tính để bàn.

Việc thực hiện dòng lệnh sẽ là thùng rác . Không có một cái nhìn gần hơn, nó dường như cung cấp tính tự do mà bạn muốn. Nếu không, hãy cho chúng tôi biết đây chỉ là một giải pháp một phần.

Theo như sử dụng bất kỳ chương trình nào thay thế / bí danh cho rmcó liên quan, có những lý do tốt để không làm điều đó. Quan trọng nhất đối với tôi là:

  • Chương trình sẽ cần hiểu / xử lý tất cả các rmtùy chọn và hành động tương ứng
  • Nó có nguy cơ làm quen với ngữ nghĩa của "rm mới" của bạn và thực hiện các lệnh với hậu quả nghiêm trọng khi làm việc trên hệ thống của người khác

Ngoài ra còn có libtrash tự động di chuyển tất cả các tệp đã xóa vào thùng rác thông qua LD_PRELOAD (nhưng dường như có một số lỗi). Autotrash giúp dọn rác một cách dễ dàng.
jofel

Tôi đang tự hỏi về thói quen sử dụng thói quen sử dụng rm. Thật không may, tôi đã có thói quen.
Konrad Rudolph

@jofel: libtrash có một khái niệm thực sự tốt đẹp. Một vài lớp sâu hơn các phương pháp khác. Thật đáng tiếc, đó là lỗi (và có vẻ không hoạt động nhiều).
zpea

4
@KonradRudolph: Tôi có nghĩa là người ta đã quen với thực tế rằng rm (cái được thay thế) không thực sự xóa bất cứ thứ gì, vì vậy người ta ít cẩn thận hơn, vì luôn luôn có thể khôi phục. Tất nhiên, sử dụng rm chính nó không phải là một điều xấu, cũng không quen với nó.
zpea

4
Tôi đã kết thúc việc sử dụng giải pháp này và vô hiệu hóa rmvì vậy tôi không thể vô tình sử dụng nó (vẫn còn /bin/rmtrong trường hợp tôi thực sự cần nó).
Konrad Rudolph


7

Các câu trả lời trước đề cập đến các lệnh trash-clirmtrash. Không có cái nào được tìm thấy theo mặc định trên Ubuntu 18.04, nhưng lệnh gionày là. gio help trashĐầu ra chỉ huy :

Usage:
  gio trash [OPTION…] [LOCATION...]

Move files or directories to the trash.

Options:
  -f, --force     Ignore nonexistent files, never prompt
  --empty         Empty the trash

Tôi đã thử nghiệm bằng cách sử dụng gio trash FILENAMEtrên dòng lệnh và nó hoạt động giống như tôi đã chọn tệp trong trình duyệt tệp và nhấp vào nút DEL: tệp được chuyển đến thư mục Thùng rác của máy tính để bàn. (Lệnh không nhắc xác nhận mặc dù tôi không sử dụng -ftùy chọn.)

Xóa các tệp theo cách này là có thể đảo ngược, trong khi thuận tiện hơn là xác định lại rmđể rm -iđảm bảo an toàn và phải xác nhận từng thao tác xóa, điều này vẫn khiến bạn không gặp may nếu bạn vô tình xác nhận việc xóa mà bạn không nên xóa.

Tôi đã thêm vào alias tt='gio trash'tập tin định nghĩa bí danh của tôi; ttlà một bản ghi nhớ cho Thùng rác.

Đã thêm vào chỉnh sửa vào 2018-06-27: Trên các máy chủ, không có thư mục rác tương đương. Tôi đã viết kịch bản Bash sau đây thực hiện công việc; trên các máy tính để bàn, nó sử dụng gio trashvà trên các máy khác, di chuyển (các) tệp được cung cấp dưới dạng tham số vào thư mục rác mà nó tạo. Script được cập nhật vào 2019-09-05.

#!/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 "$@" ; 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

5

Có một tiện ích nhỏ gọi là rmtrash thực hiện điều này.

Nó dường như không đáp ứng với các thông số như -rhoặc -f(về cơ bản là nó chỉ di chuyển tệp / thư mục vào thư mục ~ / .Trash), nhưng nó sẽ không ghi đè lên các tệp có cùng tên (nó gắn thêm "Sao chép" vào các tập tin / thư mục giống như tên).

Để cài đặt với bia

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

github.com/nateshmbhat/rm-trash . "Rm-thùng rác", xử lý tên tệp trùng lặp và xóa đệ quy. Kiểm tra nó ra.
Natesh bhat 16/12/18

4

Đây là một hệ thống rác nhanh và bẩn, đối phó với xung đột tên và thậm chí cho phép nhiều tệp bị xóa trên cùng một đường dẫn miễn là bạn không xóa nhiều hơn một tệp mỗi giây.

Cảnh báo: Tôi đã nhập mã này trực tiếp vào trình duyệt của mình. Có lẽ nó đã bị hỏng. Đừng sử dụng nó trên dữ liệu sản xuất.

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
)

Các vấn đề đã biết:

  • Không đối phó duyên dáng nếu bạn cố gắng xóa cùng một tệp nhiều lần.
  • Thư mục thùng rác có thể trở nên rất lớn, các tệp nên được gửi vào thư mục con dựa trên một vài chữ số đầu tiên của hàm băm.
  • trashnên đối phó với các dòng mới trong tên tệp, nhưng untrashkhông phải vì nó phụ thuộc grepvà các dòng mới không được thoát trong tệp siêu dữ liệu.

2

Bắt đầu bằng cách xác định move_to_trashhàm:

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

Sau đó, bí danh rmcho điều đó:

alias rm='move_to_trash'

Bạn luôn có thể gọi cũ rmbằng cách thoát nó bằng dấu gạch chéo ngược, như thế này : \rm.

Tôi không biết làm thế nào để làm cho thư mục rác trống khi khởi động lại (tùy thuộc vào hệ thống của bạn, bạn có thể phải xem xét các rc*tập lệnh), nhưng cũng có thể đáng để tạo một crontác vụ làm trống thư mục theo định kỳ.


2
Thật không may, đó là phần dễ ...: /
Konrad Rudolph

Tập lệnh này cũng có thể tạo một tệp văn bản trong một thư mục ẩn cho mỗi tệp chứa thư mục chứa trong đó. Một tập lệnh khôi phục có thể đọc vị trí cũ và di chuyển nó trở lại.
ephsmith

Điều này cũng có nguy cơ nhiều tệp bị xóa có cùng tên sẽ va chạm vào thư mục rác và chỉ có tệp "bị xóa" cuối cùng sẽ tồn tại để có thể được phục hồi.
sát thủ

@killermist, vâng. Tất nhiên người ta sẽ cần phải làm một cái gì đó bổ sung với lệnh di chuyển. Đặt tên cho tệp "rác" bất cứ điều gì bạn muốn và giữ đường dẫn gốc: | Tất cả điều này hét lên "tại sao lại tạo ra bánh xe". Có những giải pháp cho vấn đề này.
ephsmith

Ngoài ra, sử dụng một tên bí danh khác. Làm việc trên một máy khác mà không có bí danh của bạn, một cuộc gọi đến rmvà đi các tệp của bạn. delcó thể là một lựa chọn tốt hơn
glenn jackman

1

Bạn có thể sử dụng del của tôi:

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

del di chuyển tệp trong thư mục .del / thư mục con (và quay lại)

cách sử dụng: del [-v] [-u] tập tin
       del [-v] -p [-r] [-d ngày] [thư mục]
       del [-v] -l
tùy chọn: -v chế độ dài dòng
         -u phục hồi tập tin
         -p thanh lọc các tệp đã xóa [cũ hơn -d ngày]
         -r đệ quy (tất cả các thư mục con)
         -l danh sách các tập tin bị xóa
ví dụ: del * .tmp # xóa tất cả các tệp * .tmp
          del -u project.pl # undelete project.pl
          del -vprd 2 # verbose thanh lọc các tệp đã cũ hơn 2 ngày

0

Trong KDE 4.14.8, tôi đã sử dụng lệnh sau để di chuyển tệp vào thùng rác (như thể nó đã bị xóa trong Cá heo):

kioclient move path_to_file_or_directory_to_be_removed trash:/

Phụ lục I: Tôi tìm thấy về lệnh với

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

Phụ lục II: hàm (sau đó lấy nguồn trong .bashrc của bạn)

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 "$@" ;
    do
        kioclient move $i trash:/ && echo "$i was trashed"
    done
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.