The previous answers mention commands trash-cli
and rmtrash
. Neither of those are found by default on Ubuntu 18.04, but the command gio
is. Commanding gio help trash
outputs:
Usage:
gio trash [OPTION…] [LOCATION...]
Move files or directories to the trash.
Options:
-f, --force Ignore nonexistent files, never prompt
--empty Empty the trash
I tested using gio trash FILENAME
on the command line, and it works just like I'd selected the file in the file browser and clicked the DEL button: the file is moved to the desktop's Trash folder. (The command doesn't prompt for confirmation even though I did not use the -f
option.)
Deleting files this way is reversible, while being more convenient than redefining rm
to be rm -i
for safety and having to confirm each deletion, which still leaves you out of luck if you accidentally confirm a deletion you shouldn't have.
I added alias tt='gio trash'
to my alias definitions file; tt
is a mnemonic for "to trash".
Added on edit on 2018-06-27: On server machines, there is no equivalent of a trash directory. I've written the following Bash script that does the job; on desktop machines, it uses gio trash
, and on other machines, moves the file(s) given as parameter(s) to a trash directory it creates. The script is tested to work; I use it all the time myself. Script updated on 2024-04-12.
#!/bin/bash
# move_to_trash
#
# Teemu Leisti 2024-04-12
#
# USAGE:
#
# Move the file(s) given as argument(s) to the trash directory, if they are
# not already there.
#
# RATIONALE:
#
# The script is intended as a command-line equivalent of deleting a file or
# directory from a graphical file manager. On hosts that implement the
# FreeDesktop.org specification on trash directories (hereon called "the trash
# specification"; see
# https://specifications.freedesktop.org/trash-spec/trashspec-latest.html),
# that action moves the target file(s) to a built-in trash directory, and that
# is exactly what this script does.
#
# On other hosts, this script uses a custom trash directory (~/.Trash/). The
# analogy of moving a file to trash is not perfect, as the script does not
# offer the functionalities of restoring a trashed file to its original
# location or emptying the trash directory. Rather, it offers an alternative
# to the 'rm' command, thereby giving the user the peace of mind that they can
# still undo an unintended deletion before emptying the custom trash
# directory.
#
# IMPLEMENTATION:
#
# To determine whether it's running on a host that implements the trash
# specification, the script tests for the existence of (a) the gio command and
# (b) either directory $XDG_DATA_HOME/Trash/, or, if that environment variable
# hasn't bee set, of directory ~/.local/share/Trash/. If the test yields true,
# the script relies on calling 'gio trash'.
#
# On other hosts:
# - There is no built-in trash directory, so the script creates a custom
# directory ~/.Trash/, unless it already exists. (The script aborts if
# there is an existing non-directory ~/.Trash.)
# - The script appends a millisecond-resolution timestamp to all the files
# it moves to the custom trash directory, to both inform the user of the
# time of the trashing, and to avoid overwrites.
# - The user will have to perform an undo by commanding 'mv' on a file or
# directory moved to ~/.Trash/.
# - The user will have to empty the custom trash directory by commanding:
# rm -rf ~/.Trash/* ~/.Trash/.*
#
# The script will not choke on a nonexistent file. It outputs the final
# disposition of each filename argument: does not exist, was already in trash,
# or was moved to trash.
#
# COPYRIGHT WAIVER:
#
# The author dedicates this Bash script to the public domain by waiving all of
# their rights to the work worldwide under copyright law, including all
# related and neighboring rights, to the extent allowed by law. You can copy,
# modify, distribute, and perform the script, even for commercial purposes,
# all without asking for permission.
if [ -z "$XDG_DATA_HOME" ] ; then
xdg_trash_directory=$(realpath ~/.local/share/Trash/)
else
xdg_trash_directory=$(realpath $XDG_DATA_HOME/Trash/)
fi
gio_command_exists=0
if $(command -v gio > /dev/null 2>&1) ; then
gio_command_exists=1
fi
host_implements_trash_specification=0
if [[ -d "${xdg_trash_directory}" ]] && (( gio_command_exists == 1 )) ; then
# Executing on a host that implements the trash specification.
host_implements_trash_specification=1
trash_directory="${xdg_trash_directory}"
else
# Executing on other host, so attempt to use a custom trash directory.
trash_directory=$(realpath ~/.Trash)
if [[ -e "${trash_directory}" ]] ; then
# It exists.
if [[ ! -d "${trash_directory}" ]] ; then
# But is not a directory, so abort.
echo "Error: ${trash_directory} exists, but is not a directory."
exit 1
fi
else
# It does not exists, so create it.
mkdir "${trash_directory}"
echo "Created directory ${trash_directory}"
fi
fi
# Deal with all filenames (a concept that covers names of both files and
# directories) given as arguments.
for file in "$@" ; do
file_to_be_trashed=$(realpath -- "${file}")
file_basename=$(basename -- "${file_to_be_trashed}")
if [[ ! -e ${file_to_be_trashed} ]] ; then
echo "does not exist: ${file_to_be_trashed}"
elif [[ "${file_to_be_trashed}" == "${trash_directory}"* ]] ; then
echo "already in trash: ${file_to_be_trashed}"
else
# ${file_to_be_trashed} exists and is not yet in the trash directory,
# so move it there.
if (( host_implements_trash_specification == 1 )) ; then
gio trash "${file_to_be_trashed}"
else
# Move the file to the custom trash directory, with a new name that
# appends a millisecond-resolution timestamp to the original.
head="${trash_directory}/${file_basename}"_TRASHED_ON_
move_file_to="${head}$(date '+%Y-%m-%d_AT_%H-%M-%S.%3N')"
while [[ -e "${move_file_to}" ]] ; do
# Generate a new name with a new timestamp, as the previously
# generated one denoted an existing file or directory. It's very
# unlikely that this loop needs to be executed even once.
move_file_to="${head}$(date '+%Y-%m-%d_AT_%H-%M-%S.%3N')"
done
# There is no file or directory named ${move_file_to}, so
# we can use it as the move target.
/bin/mv "${file_to_be_trashed}" "${move_file_to}"
fi
echo "moved to trash: ${file_to_be_trashed}"
fi
done
gvfs-trash
in the past, but never had a need to restore from the command-line until you sparked my curiosity. The answer to the linked question may be of help.rm
and, yes, I occasionally delete the wrong files by accident. Thanks to automatic backups this usually hasn’t been an issue (there are rare exceptions when working on scratch space, but by definition these files aren’t important … at least, ideally).