NAME File::Trash::FreeDesktop - Trash files VERSION This document describes version 0.207 of File::Trash::FreeDesktop (from Perl distribution File-Trash-FreeDesktop), released on 2023-11-21. SYNOPSIS use File::Trash::FreeDesktop; my $trash = File::Trash::FreeDesktop->new; # list available (for the running user) trash directories my @trashes = $trash->list_trashes; # list the content of a trash directory my @content = $trash->list_contents("/tmp/.Trash-1000"); # list the content of all available trash directories my @content = $trash->list_contents; # trash a file $trash->trash("/foo/bar"); # specify some options when trashing $trash->trash({on_not_found=>'ignore'}, "/foo/bar"); # recover a file from trash (untrash) $trash->recover('/foo/bar'); # untrash a file from a specific trash directory $trash->recover('/tmp/file', '/tmp/.Trash-1000'); # specify some options when untrashing $trash->recover({on_not_found=>'ignore', on_target_exists=>'ignore'}, '/path'); # empty a trash directory $trash->empty("$ENV{HOME}/.local/share/Trash"); # empty all available trashes $trash->empty; DESCRIPTION This module lets you trash/erase/restore files, also list the contents of trash directories. This module follows the freedesktop.org trash specification [1], with some notes/caveats: * For home trash, $HOME/.local/share/Trash is used instead of $HOME/.Trash This is what KDE and GNOME use these days. * Symlinks are currently not checked The spec requires implementation to check whether trash directory is a symlink, and refuse to use it in that case. This module currently does not do said checking. * Currently cross-device copying is not implemented/done It should not matter though, because trash directories are per-filesystem. Keywords: recycle bin THE TRASH STRUCTURE The following is a short description of the trash structure. A trash directory is a per-filesystem, per-user directory structure to allow files to be "trashed", i.e. to be put inside and to be recovered to its original location later should a user changes his/her mind and wants the files back. Otherwise, user can "empty" the trash to delete files permanently. A trash directory, e.g. "/home/USER1/.local/share/Trash", contains two subdirectories: "info" and "files". The "files" contain the actual trashed files and their name must be unique. Thus if "/home/USER1/foo.txt" is trashed and then another "/home/USER1/foo.txt" is trashed again, the second file must be renamed to "/home/USER1/foo (1).txt" or something else. The "info" subdirectory contains the metadata for each trashed file, with each metadata put in an INI of the same name of the correspoonding file in "files" with ".trashinfo" suffix, under the INI "Trash Info" section. Known INI parameters include: "Path" (the original name/path of the trashed file) and "DeletionDate" (date and time, in ISO8601 format). NOTES Weird scenario: /PATH/.Trash-UID is mounted on its own scenario? How about /PATH/.Trash-UID/{files,info}. METHODS $trash = File::Trash::FreeDesktop->new(%opts) Constructor. Known options: * home_only Bool. If set to true, instruct the module to just look for trash directory under the home directory and not search other filesystem mountpoints for possible trash directories. $trash->list_trashes() => LIST List user's existing trash directories on the system. Return a list of trash directories. Sample output: ("/home/mince/.local/share/Trash", "/tmp/.Trash-1000") $trash->list_contents([ \%opts ], [ $trash_dir ]) => LIST List contents of trash director(y|ies). If $trash_dir is not specified, list contents from all existing trash directories. Die if $trash_dir does not exist or inaccessible or corrupt. Return a list of records like the sample below: ({entry=>"file1", path=>"/home/mince/file1", deletion_date=>1342061508, trash_dir=>"/home/mince/.local/share/Trash"}, {entry=>"file1.2", path=>"/home/mince/sub/file1", deletion_date=>1342061580, trash_dir=>"/home/mince/.local/share/Trash"}, {entry=>"dir1", path=>"/tmp/dir1", deletion_date=>1342061510, trash_dir=>"/tmp/.Trash-1000"}) The "path" key is the original path of the file before it is put into the trash. Known options: * suffix Str. * path_wildcard Wildcard pattern to be matched against path. Only matching entries will be returned. * path_re Regexp pattern to be matched against path. Only matching entries will be returned. * path Exact matching against path. Only matching entries will be returned. * filename_wildcard Wildcard pattern to be matched against the filename part of path. Only matching entries will be returned. * filename_re Regexp pattern to be matched against the filename part of path. Only matching entries will be returned. * filename Exact matching against filename part of path. Only matching entries will be returned. * mtime Int. Only return entries where the trashed file's modification time matches this <value. $trash->trash([\%opts, ]$file) => STR Trash a file (move it into trash dir). Will try to find a trash dir that resides in the same filesystem/device as the file and is writable. "$home/.local/share/Trash" is tried first, then "$device_root/.Trash-$uid", then "$device_root/tmp/.Trash-$uid". Will die if no suitable trash dir is found. Will also die if moving file to trash (currently using rename()) fails. Upon success, will return the location of the file in the trash dir (e.g. "/tmp/.Trash-1000/files/foo"). If first argument is a hashref, it will be accepted as options. Known options: * on_not_found => STR (default 'die') Specify what to do when the file to be deleted is not found. The default is 'die', but can also be set to 'ignore' and return immediately. * suffix => STR Pick a suffix. Normally, file will be stored in "files/ORIGNAME" inside trash directory, or, if that file already exists, in "files/ORIGNAME.1", "files/ORIGNAME.2", and so on. This setting overrides this behavior and picks "files/ORIGNAME.SUFFIX". Can be used to identify and restore particular file later. However, will die if file with that suffix already exists, so be sure to pick a unique suffix. $trash->recover([\%opts, $orig_path, $trash_dir]) Recover a file or multiple files from trash. Unless $trash_dir is specified, will search in all existing user's trash dirs. Will die on errors. You need to specify the original path of the file before it was trashed, but you can also specify unqualified filename (without path) and/or path patterns via options (see below) instead. If no files are found, the method will simply return. If first argument is a hashref, it will be accepted as options. Known options: * filename See list_contents(). * filename_wildcard See list_contents(). * filename_re See list_contents(). * path See list_contents(). * path_wildcard See list_contents(). * path_re See list_contents(). * mtime See list_contents(). * on_target_exists => STR (default 'die') Specify what to do when restore target already exists. The default is 'die', but can also be set to 'ignore' and return immediately. * mtime => INT Only recover file if file's mtime is the one specified. This can be useful to make sure that the file we recover is really the one that we trashed earlier, especially if we trash several files with the same path. (Ideally, instead of mtime we should use some unique ID that we write in the .trashinfo file, but I fear that an extra parameter in .trashinfo file might confuse other implementations.) See also "suffix", which is the recommended way to identify and recover particular file. * suffix => STR Only recover file having the specified suffix, chosen previously during trash(). $trash->erase([ \%opts, ] $file[, $trash_dir]) => LIST Erase (unlink()) a file or multiple files in trash. Unless $trash_dir is specified, will empty all existing user's trash dirs. Will ignore if file does not exist in trash. Will die on errors. To erase multiple files based on wilcard or regexp pattern, use the options. See list_contents(). Return list of files erased. $trash->empty([$trash_dir]) => LIST Empty trash. Unless $trash_dir is specified, will empty all existing user's trash dirs. Will die on errors. Return list of files erased. ENVIRONMENT PERL_FILE_TRASH_FREEDESKTOP_DEBUG Bool, if set to true will produce additional logging statements using Log::ger at the "trace" level. HOMEPAGE Please visit the project's homepage at <https://metacpan.org/release/File-Trash-FreeDesktop>. SOURCE Source repository is at <https://github.com/perlancar/perl-File-Trash-FreeDesktop>. SEE ALSO Specification <https://freedesktop.org/wiki/Specifications/trash-spec> CLI utilities * App::TrashUtils A set of CLI's written in Perl: trash-empty, trash-list, trash-list-trashes, trash-put, trash-restore, trash-rm. * trash-u (from App::trash::u) An alternative CLI, with undo support. * trash-cli A set of CLI's written in Python: "trash-empty", "trash-list", "trash-put", "trash-restore", "trash-rm". <https://github.com/andreafrancia/trash-cli> Related CPAN modules * Trash::Park Different trash structure (a single CSV file per trash to hold a list of deleted files, files stored using original path structure, e.g. "home/dir/file"). Does not create per-filesystem trash. * File::Trash Different trash structure (does not keep info file, files stored using original path structure, e.g. "home/dir/file"). Does not create per-filesystem trash. * File::Remove File::Remove includes the trash() function which supports Win32, but no undeletion function is provided at the time of this writing. AUTHOR perlancar <perlancar@cpan.org> CONTRIBUTOR Steven Haryanto <stevenharyanto@gmail.com> CONTRIBUTING To contribute, you can send patches by email/via RT, or send pull requests on GitHub. Most of the time, you don't need to build the distribution yourself. You can simply modify the code, then test via: % prove -l If you want to build the distribution (e.g. to try to install it locally on your system), you can install Dist::Zilla, Dist::Zilla::PluginBundle::Author::PERLANCAR, Pod::Weaver::PluginBundle::Author::PERLANCAR, and sometimes one or two other Dist::Zilla- and/or Pod::Weaver plugins. Any additional steps required beyond that are considered a bug and can be reported to me. COPYRIGHT AND LICENSE This software is copyright (c) 2023, 2017, 2015, 2014, 2012 by perlancar <perlancar@cpan.org>. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. BUGS Please report any bugs or feature requests on the bugtracker website <https://rt.cpan.org/Public/Dist/Display.html?Name=File-Trash-FreeDeskto p> When submitting a bug or request, please include a test-file or a patch to an existing test-file that illustrates the bug or desired feature.