I accidentially copied my whole home directory into one of my subdirectories, causing me to exceed my disk quota on a server.
Or does anyone know how to undo a command in general?
bashundo
I accidentially copied my whole home directory into one of my subdirectories, causing me to exceed my disk quota on a server.
Or does anyone know how to undo a command in general?
Hopefully, I correctly get what You are looking for. If so, there seems to be WinAPI method - ReadDirectoryChangesW that might do what You expect.
I am not sure if following approach will work with file operation history or only display changes made after the time it is used, however, as this approach is not that different and might be used in scenario You provided, I will mention that even it might be slightly off-topic:
You could be able to connect FileSystemWatcher object to a folder (yet the link's topic is different, this IMHO gives nice overview of the class purpose) – it is C# .NET class, I know, but what is C# can be made PowerShell as shown by this script from Microsoft's Script Center.
You might consider a 3rd party solutions such as Windows Explorer tracker that seems to do the same (I believe they rather use (documented) API calls than reverse-engineering techniques – but You seemed bit concerned about them, so I only looked-up one).
And last but not least, You might even consider writing a simple WPF application based on FileSystemWatcher or bit more complex WPF application calling ReadDirectoryChangesW method.
Yes. My idea is to call a shell function (upon a keystroke) that will manipulate READLINE_LINE
using the ${variable@Q}
feature.
Relevant parts of documentation:
${parameter@operator}
The expansion is either a transformation of the value of
parameter
or information aboutparameter
itself, depending on the value ofoperator
. Eachoperator
is a single letter:
Q
The expansion is a string that is the value ofparameter
quoted in a format that can be reused as input.
(source)
READLINE_LINE
The contents of the Readline line buffer, for use withbind -x
[…].
(source)
The following works in Bash 4.4.20:
_quote_all() { READLINE_LINE="${READLINE_LINE@Q}"; }
bind -x '"\C-x\C-o":_quote_all'
To test the solution, prepare a command in the command line (do not execute), for example
d="$(LC_ALL=C date)"; printf 'It'\''s now %s\n' "$d"
(Quoting and the entire command could be simplified. It's deliberately like this. And you can execute it to make sure it's a valid command, but place it back in the command line before you proceed.)
Hit Ctrl+x,Ctrl+o and it will be properly quoted/escaped for our purpose. It will look like this:
'd="$(LC_ALL=C date)"; printf '\''It'\''\'\'''\''s now %s\n'\'' "$d"'
Now all you need to do is to add watch
(or ssh …
, or whatever) in front and execute. If it's watch
then note the header is like
Every 2.0s: d="$(LC_ALL=C date)"; printf 'It'\''s now %s\n' "$d"
It contains the original command. The command properly got to watch
, no part was interpreted prematurely.
For convenience consider this variant:
_quote_all() { READLINE_LINE=" ${READLINE_LINE@Q}"; READLINE_POINT=0; }
It will prepare the line and place the cursor at the beginning, so you can type watch
right away. Or maybe even this variant (it deliberately goes under a different name, we're creating a separate binding for it):
_prepend_watch() { READLINE_LINE="watch ${READLINE_LINE@Q}"; READLINE_POINT=6; }
bind -x '"\C-x\C-w":_prepend_watch'
Now Ctrl+x,Ctrl+w handles quoting, inserts watch
automatically and places the cursor in the right position for you to type options.
With yet another function using READLINE_POINT
it's possible to handle the following scenario: type watch
(or ssh …
) followed by a command, where quoting/escaping is as if the command was going to be executed directly. Place the cursor where the command begins, hit the keystroke and let the function modify everything from the cursor to the end of the line. I'm not providing such function here; write it by yourself if you need it.
You can stack the solution. I mean you can go from this
df -h | grep -v tmpfs
to this
watch 'df -h | grep -v tmpfs'
to this
ssh hostB -t 'watch '\''df -h | grep -v tmpfs'\'''
to this
ssh -t hostA 'ssh -t hostB '\''watch '\''\'\'''\''df -h | grep -v tmpfs'\''\'\'''\'''\'''
(yes, I know ssh -J
)
by only hitting Ctrl+x,Ctrl+o and appending one or few words in front in each step.
Best Answer
Bash is just a command-line interpreter - it does what you tell it to do and doesn't have an undo helper program. You're best of just deleting the subdirectory with something like: