Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Careful with rm:

    r
    rm
    rm -
    rm -rf
    rm -rf ~
    rm -rf ~/
    rm -rf ~/tmp
    # where did my files go?


Right, it's theoretically dangerous, or I'd say practically: "please think when using it"... though I personally couldn't find any other serious problematic example other than typing something clearly dangerous in the first place. And I personally found it immensely useful in the other, non-dangerous cases. So I just took the chance and went with the idea, and then wanted to share it with you, so you might also find it useful, maybe! :) Also... umm... you know, a tool isn't really truly Unixy if you can't hurt yourself with it, right? ;P

That said, I'm starting to think — should I include a note about the potential dangers in the readme?... they seemed glaringly obvious to me (at least in case of rm-like commands), but can there be readers/users, to whom they'd not be obvious?...

edit: Ok, I tried to add a warning in the Readme, that's something I can do easily, and if it helps someone, worth it...


I'm not so versant about the state of permission / capability systems on Linux.

But if there is a way for you to drop the capability to modify the filesystem before running the first pipeline, you should definitely do it by default (and provide a switch to override it if somebody knows what they are doing.)


It seems like a whitelist of safe commands would be a good idea? The user can override with -f if they want to live dangerously.

Even rm has a -f flag to override some safety measures, though the defaults aren't very safe.


Even better, put it into a non-privileged user by default with no write permission.


Sounds interesting; but is there any way I could change to a different user if not running as root?... also, even if yes, how do I dynamically create a non-privileged user, or find a pre-existing one?


I would try creating a non-privileged user "up" during installation and switch to that user under the hood before running the command via `su`.

(Though it would complicate installation which is effectively non-existent since there is a single binary; and tightly couple the application with the environment. It's a trade-off anyway.)

(Edit: Somebody mentioned the user "nobody" which seems to be a better alternative.)

In any case I think that the whitelist approach would work better as it would be nice if the tool knew in advance which commands work properly and which ones don't. That way it could inform its users about the allowed & unallowed commands.

Commands with side effects (or "impure" in the FP terminology) don't make much sense anyway to be used within this. The main value is fast iteration, in order to verify the expected output of the pipeline. For me it doesn't make much sense to use it with commands whose main purpose is to modify the filesystem instead of generating / transforming data and writing it to stdout.

So the criteria for the commands that would make it into the whitelist may be "not having side effects", "writing to stdout", and optionally "reading from stdin".

Fastly iterating side effects is unsafe as well, as has already been pointed out.

This can be a fine data analysis tool actually, unfortunately only for command line geeks. The experience is actually not so far from analyzing data with VIM interactively by piping it to an external UNIX command and getting the result dataset back into the editor. VIM hackers will know :)


One thing to watch out for is that a process running as "nobody" has permission to manipulate (e.g. kill) other processes running as that user. This sometimes includes system processes. Allowing any user to run arbitrary commands as nobody is technically a privilege escalation, and therefore should be avoided.

A single-purpose user with its own group would have this problem only to a lesser degree (you'd be able to mess with other users' "up" invocations, but not any system processes).


I didn't know this (I'm not much of a sysadmin), thank you for the information!


Could you make a `[caller]_up` user for each different user?


I actually like the user idea better. The problem with a whitelist is that even useful commands can have subtle or little known dangerous modes, like "find . -exec rm {}"


Ah. Good point. Whitelisting commands would have already been a bit painful, and now your comment shows that the parameters need to be whitelisted/blacklisted as well, which would be crazy.

In a world in which shell commands respected the UNIX philosophy, "find" wouldn't have a silly option like "exec", and other commands wouldn't mix read / write / pure data transform operations in a single command.

But it is what it is. So yeah, protection probably needs to be implemented in the user level, for maximum safety.

Maybe an alternative and/or complementary solution would be to profile each inputted command to detect if they are attempting write operations (maybe with "strace" or something like that), and cancel the evaluation of the command in the next iterations and/or show a warning.


> The experience is actually not so far from analyzing data with VIM interactively by piping it to an external UNIX command and getting the result dataset back into the editor. VIM hackers will know :)

Do you mean something like this?

   :r! lshw | grep network -A2 | grep : | cut -d: -f2- | paste - -
I'm not versed well enough in vim scripting but I suppose there's a way to loop on that on each <CR> or even keypress (like fzf/ctrlp).


> Do you mean something like this?

    :r! lshw | grep network -A2 | grep : | cut -d: -f2- | paste - -
Not exactly. More like:

- Open vim with the output of `lshw` as content:

    lshw | vim -
- Examine the raw data

- Send the whole content of the buffer as standard input to the given command and rewrite the buffer with the data read from the standard output of it:

    :%! grep network -A2
- Examine the returned dataset. Iterate:

    :%! grep :
- Examine & iterate:

    :%! cut -d: -f2-
- Examine & iterate:

    :%! paste - -

This way, you can examine the output of each step of the pipeline individually, so you can construct your command incrementally. And it is up to you to decide at which point a command will be run instead of it being run automatically following every keypress.

Since the dataset returned by the last command will be visible in the current buffer, you will be able to examine & play with it full screen. You will be able to clean or transform some parts manually (this is frequently needed in data science).

You can always return to the previous/next dataset by pressing u/Ctrl+R (for undo and redo), and examine your command history by pressing ":" and then Ctrl+P/Ctrl+N. (Or you can open the command history quickfix menu by pressing "q:" to view/copy the last several commands at once.)

And since you are in a full blown text editor, you can take advantage of other helpful features such as folding, saving the current dataset to a temporary file, etc.

If you are comfortable with more than a few UNIX filters, VIM can be a very convenient and fun tool to play with data.


Nice tool! Your main use case for destroying files is “xargs rm”, which would be used when receiving a piped argument list.

Could you have this command run as user “nobody” by default, and have a flag to run as a real user? Or as others have mentioned, use capabilities on the spawned processes to prevent anything other than standard input/output?


This is one of the main reasons that I ultimately decided for my Strukt.app to not be built on top of built-in shell commands. For an interactive tool, it's crucial for each operation to be able to report whether it's idempotent, does writeback, etc.

Strukt doesn't do 'rm' yet (and nobody has ever requested it), but it does have other operations that do writeback. Once you add one, automatic updates are disabled, and you have to explicitly run the pipeline each time you want it run.

We really need a new cross-platform low-level framework for lego-like operations, like shell commands but updated for the 21st century.


PowerShell has a design answer for this - each cmdlet takes parameters, but the environment provides common parameters relating to loging, error handling, storing output in variables, and it provides support for "WhatIf" and transactions.

WhatIf instructs the command not to make any changes, but merely to log what it would do. You can "Remove-Item C:\Windows -Force -WhatIf" and it will output "What if: Performing the operation "Remove Directory" on target "C:\windows"" but not delete anything.

(implementing support for "whatif" is optional, so you can't casually use it on any given cmdlet without first checking that cmdlet supports it and makes sensible use of the parameter instead of ignoring it, but the idea is there).


Yep, that's basically the solution that I came up with, too. I have a "dry-run?" flag planned, if I ever end up with enough writeback operations where it'd be useful.

(That's the common Unix shell name for it, though it's not entirely consistent -- which is another problem with using Unix built-ins!)

One thing I've noticed is that it's really frustrating (and not at all helpful) to require perfect validity from a shell-like tool. There's just too many times where you want to edit something into something else, without needing to find a perfect path of valid and meaningful syntax at every intermediate step. So if you have a flag on an operation that doesn't understand that flag, the flag will have a (?) badge to indicate that it won't be understood or used, but the pipeline will still run.


I feel this app should have a limited free mode, like "10" results or something. I'd love to try it, but just trying for $24 seems like a gamble, as I am not sure I'd like it or not.


I found a new variation recently. Luckily all my code was checked in.

Meant to type:

    rm -rf node_modules && npm install
Question: what's immediately next to the & key on a keyboard?

Answer: *

Actually typed

    rm -rf node_modules ** npm install
Oops.


If you’re on Mac OS X , try installing the “trash” app (from brew iirc) and retrain yourself to never use bare rm anymore. There’s probably similar tools on Linuxes.

Theory is: rm is dangerous and should not be used day to day.


Using btrfs on Linux I have a job that takes a CoW snapshot of the whole filesystem every 10 minutes just so that I can undo whoopsies. I don't retain all of these snapshots, only the most recent one.


Or simply have local, quick, regular and tested backups.


yikes!

It's always been surprising to me that their isn't a built in "undo" to `rm`

e.g. why doesn't `rm` just move files to /tmp?


You can make a trash command if you want and a cron job to periodically remove everything over x days old.

The default rm doesn't do this because shell users are supposed to be able to figure out how not to delete things they want to keep.

Kind of like not pointing a gun at people who you don't want to kill.

The undo for rm is regular backups.


Journaling works well here too, but in my experience the interface sucks on every platform. Eg, it should be trivial to view recent unlinks. There’s simply more reason to invest in backup software, which has an excellent interface even if it is a “heavy” operation.


That is not what journaling is for. Journaling is for maintaining filesystem consistency. If you want access to recently deleted files that is a different task.

On my system I have snapshots of my home directory created every 15 minutes. Not quite the same thing, but it also helps me when I have incorrectly modified a file.


Well, it’s a loss for us all that the designers were not more imaginative.


> e.g. why doesn't `rm` just move files to /tmp?

And do what when tmp gets full and services & applications start crashing?

When someone implements that undo, someone's going to need to write a tool that really does remove files, really. Will the next guy wonder why really-rm doesn't have undo built in?


What about undo that expires in 1 minutes? Gmail website does that for sent emails (for 5 seconds I guess).


> What about undo that expires in 1 minutes? Gmail website does that for sent emails (for 5 seconds I guess).

Same question as parent: "And do what when tmp gets full and services & applications start crashing?"


You could do what is more or less an industry standard when it comes to this and warn the user that there's not enough room to allow an undo when deleting said file(s) and prompt if they want to delete it permanently instead.

It's not rocket surgery.


I'm never that nervous when doing `rm -fr` on my Plan9 or FreeBSD or macOS systems, which all have frequent snapshots turned on.

We could all just work with WORM drives instead.


I am similarly not worried on my Linux system, which also has frequent snapshots turned on. Instead I worry about bugs in btrfs, but that is another story.


> It's always been surprising to me that their isn't a built in "undo" to `rm`

Have a look at either the `trash-cli` package by Andrea Francia.


Mildly related, I wish rm would check that you’re not unlinking the current directory. I’ve never wanted the behavior when I accidentally invoke it.


alias rm to rm -i (always prompt)

I don't do this because my idiocy must be punished disproportionately. Also, you end up automatically pressing y enter.


sysadmin here, yep, aliases are how I deal with dangerous commands as well.


And when you get used to your carefully curated crutches and have to work on someone else's machine, that's where the fun starts.

Aliases can be way more dangerous; think about what you're doing. This is what backups are for.


This is true, which is why I dont use them much!


You could easily make rm inactive (remove execute flag, move it, ...) and make rm an alias for send to trash (gvfs-trash, trash-cli, or whatever).


That's the first thing I thought and it's mentioned in the readme file itself.

I don't think I'd ever want to use this tool. Every keystroke could be an arbitrary command, and I wonder about the performance of commands with a lot of I/O or processing.

Conceptually it's really neat and I get it, but practically I find things like parameter completion in Fish much more useful.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: