Hacker News new | past | comments | ask | show | jobs | submit login
Do not use redirection characters in your shell prompt (tanelpoder.com)
217 points by tanelpoder on March 17, 2021 | hide | past | favorite | 127 comments



This seems to be more of "don't paste garbage into a terminal, especially as root." With a sidenote that it might be safer if your custom application command interpreter didn't use > as the prompt character. I note that Bourne shell defaults to the safer % and # characters for the prompt. The # character for root is especially safe.


Yeah. About the only relevant bit is that root prompts tend to use # as part of their prompt precisely to inject a comment character in case of mis-quotes/pastes.


Wow I never heard that! I always thought it was just some arbitrary convention I guess.


I've heard this story before, but I don't think it's true.

I think the bourne shell copied # comments from csh, which had them first. When sh first implemented them, # comments only worked in scripts, not if you typed them at the shell (i.e. if isatty(0), then # wasn't special). The fact that the prompt came before comments, and that comments didn't work interactively really makes the story sound suspect!

I don't know the origin of # in csh, but I would guess it was chosen because it looks like a CPP directive.


Hmm, wasn't # the default erase character for teletype-era Unix? And @ the "kill" character (like modern ^U)? That would have made them a little annoying to type—not annoying enough to keep them from being used for cpp, though, and https://github.com/memnoth/unix-v6/blob/master/sys/dmr/tty.c... suggests that you could type \#. (There was no "lnext" yet; it was just hardcoded to backslash.)

The actual input erase handling is on https://github.com/memnoth/unix-v6/blob/master/sys/dmr/tty.c.... The relevant struct member is declared in https://github.com/memnoth/unix-v6/blob/master/sys/tty.h#L35 and initialized to CERASE in each tty driver, for example, https://github.com/memnoth/unix-v6/blob/master/sys/dmr/kl.c#..., using the macro defined in https://github.com/memnoth/unix-v6/blob/master/sys/tty.h#L48.

So by default # was special, just to the kernel tty driver, not the shell.


That's a fair point. But in the 90s as a System V and SunOS user, I saw some discussions happen on Usenet, and by the time X was commonplace, the myth/rationale was commonplace.


Even then, though, that was over a decade after the fact, and people were inventing explanations for things retroactively. Doug McIlroy has put the kibosh on this myth.

* https://minnie.tuhs.org/pipermail/tuhs/2017-April/011286.htm...


I don't have reference for that but I always though that CPP directives are preceded by # because the character was previously used as comment delimiter by something (probably csh). In the grand scheme of things cpp is somewhat modern invention. IIRC the first book on Unix programming I had read mentioned in passing that cpp exists but the C code examples in there did not #include anything and if some declaration was required it was just written verbatim in the example code.


Even if # isn't / wasn't special, it's still exceedingly unlikely to be a valid program name, nor is it likely for a valid program name to begin with #. The practical effect should be the same as it having been special.


Right, but the story sounds plausible because accidentally pasting '# foo > bar' would safely neuter everything else on the line.

If # isn't special, then the rest of the line is still parsed, so pasting '# foo || bar' or '# foo > baz' does do something.


Potentially, but I can pretty much guarantee that someone working on any shell has run into this problem before, and then decided not to change the # because it was so damned convenient for preventing mispastes.


This is why I hang out here!

Obligatory XKCD: https://xkcd.com/1053/


This is getting to be a tired meme.

While it doesn't apply to shell prompts, there are such things as cultural memory and institutional memory. As a member of a group or society, you are expected to have a certain baseline amount of knowledge of that culture and history.

When I was young, it was considered shameful not to know things. Now the people I work with seem to wear ignorance as a badge of pride. They think that not knowing something means that thing is not worth knowing. As if somehow not knowing something is a good thing.


> Now the people I work with seem to wear ignorance as a badge of pride. They think that not knowing something means that thing is not worth knowing. As if somehow not knowing something is a good thing.

That may be the case, due to attitudes encouraged by pop culture, etc. but it's a disastrously incorrect understanding of the comic (and parent comment). They're celebrating learning, which is the exact opposite of 'wearing ignorance as a badge of pride'.

> When I was young, it was considered shameful not to know things.

Shaming something discourages people from admitting it. A child who's ashamed to ask questions will not learn as effectively. They may learn to avoid admitting their ignorance, but that may cause problems later (struggling alone rather than asking for help, possibly leading to damage or injury, etc.).

> there are such things as cultural memory and institutional memory. As a member of a group or society, you are expected to have a certain baseline amount of knowledge of that culture and history.

How do you think the members of those groups have that knowledge? We have not (yet) evolved a genetic predisposition to grow, in utero, neuronal bundles encoding Unix shell prompt escape sequences. That's the point; everyone has all need to learn!

Still, it's better to air and discuss such takeaways!


There’s a huge gulf between admitting you don’t know something, and being proud of it.

Suggesting it was ever, or should be, somehow “shameful” to admit not knowing something, is an enemy of change and growth, and in everyday life becomes a recipe for perpetuating structural in-groups and all the systemic pathologies that go along with them.

I am also grumpy old fart but I was raised in an engineering culture that was not afraid to ask “what’s a spline?”, and I don’t regret it.


I don't mind at all when someone admits they don't know something important at work.

I'm frustrated when they admit it 6 months too late.

Ignorance is the norm, but fix it when it's necessary, don't try to hide it.


Welcome to the world of the Cult of Abstraction. I've never understood the fascination with not knowing what lurks beneath... I've just kind of grown used to it though, and have gotten used to solving the problems everyone else throws their hands in the air over for not knowing how to get deeper.

I mean, I get it in some cases; you don't need to know how things work to use them, but when things go wrong, and they always do, that's when knowing how it works (and not just how to use it) pays off.

Plus, you can articulate questions about things you don't know more effectively.


I want to curmudgeonly respond that you’re selling people short. But honestly I’m gonna repeat the theme of the comic.

You’re today’s lucky one, you get to learn something new! People shelter themselves with the familiar all the time. You have too! You started your explanation of your perspective with “when I was young”, and that’s obviously something you’ve held onto.

I’m gonna make your day. Did you know that people, in your life or waiting in the wings, are gonna be grateful for the things you can show them? The only thing you need to do is be just thrilled to introduce it, whatever it is, even if they don’t have the thrill yet.

You just gotta get enough in tune emotionally to know what they’re gonna want to know and how to tell them. That’s a fun new exploration all for you.


>As a member of a group or society, you are expected to have a certain baseline amount of knowledge of that culture and history.

How is it possible to become a member of the group or society except by hanging out with existing members and learning from them?

>Now the people I work with seem to wear ignorance as a badge of pride. They think that not knowing something means that thing is not worth knowing. As if somehow not knowing something is a good thing.

That comic is saying almost the opposite of that. The comic says that gaining knowledge is a good thing and should be celebrated.


I _think_ it started becoming commonplace around the early days of X11, although to be fair # and $ are neighbors on pretty much any keyboard layout.


> # and $ are neighbors on pretty much any keyboard layout

Aside from ISO QWERTY, AZERTY and at least 3 different QWERTZ variants, among others.


Not UK layout; shift-3 is £ and # is next to enter.

\ @ and " are in their proper positions on a UK layout as well. :|

https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2F...


That implies you should put a space before the # in the root prompt, because it's not recognized as a comment delimiter if it's in the middle of a "word".


Yep (author here), not pasting garbage into a terminal is the main point of this article. Partially, it's a rant against the way-too-trigger-happy "paste clipboard on right mouse click" terminals too.

I decided to finally write this article, after seeing a yet another "mysterious" case of a missing binary in some Oracle database server. Linux/Bash defaults are ok, but historically (coming from traditional Unix background?), people who engineer environments at least in the Oracle database server world, configure their prompts to some "corporate standard". And sometimes they end up suffixing prompts by a nice-looking ">" character, leading to this problem.

I've also seen someone set their root prompt to `root#>`. Since there's no space between the username and #, the "comment start" is not recognized and the redirection clobbering problem is still there.


Because of this problem, good terminals require confirmation before pasting any strings that contain suspicious characters, e.g. carriage returns.


I have seen a ‘good terminal’, apparently. Can you name one?


I was musing over IPython's behavior right before reading your comment... it's not a terminal, per se, but if you paste in multiple lines, the input switches into a multiline mode. This suggests that bash could handle it in the same manner without relying on a terminal application.

In my experience, the advice "don't paste garbage into your terminal" is about as useful as "don't make mistakes." Sometimes it happens when I forget to hit shift on copying from a terminal, or accidentally holding it while copying from another window. Humans make mistakes. I like seatbelts even though they've never saved my life.


Two examples: PuTTY and Windows Terminal both present confirmation dialogue boxes before pasting multiline content.


PuTTY accepts multiline pastes for me just fine, I use it with nano.


iTerm seems to do this also at least with multi line pastes - and then zsh seems to wait for you to hit enter AGAIN before executing anything.


In iTerm, Edit -> Paste Special -> Warn Before Multi-Line Paste will disable it if you don't like it. It's probably better to disable it in zsh, but I don't know how to do that. iTerm also provides the "only pop up this warning when I'm at a shell prompt", which is ironically exactly when I don't want it to pop up (since zsh/fish detect it themselves).


Using "unset zle_bracketed_paste" should do what you want, but I've only tried it in rxvt-unicode and the vte-based term I have. It stops zsh reacting to the escape sequences used by multi-line paste, see the docs for a full explanation¹.

If you were to use I'd recommend sticking it behind a "if $TERM" guard so that it you don't end up surprised if you switch to a term that doesn't warn at some point ;)

¹ http://zsh.sourceforge.net/Doc/Release/Parameters.html#index...


Xfce4-terminal prompts for confirmation when there's newline in the pasted contents.


Well, how about making it hard to do accidental input in the first place? If pasting is a problem the maybe make the actions necessary less possible to be triggered randomly?


Also don’t shell script on the fly in a production server that has data of any sort you can’t restore from a backup. It’s one giant game of Russian roulette and eventually the human is going to screw up


I feel a better takeaway is "people are sometimes going to mess up, if you can do something easy to make those mess-ups less serious, it's probably worthwhile."


What about eliminating root usage? Could sudo be used here? Or perhaps every root command should need a confirmation prompt before execution.


Yeah this feels like more of a cautionary tale about proper privilege and directory management.

Was there really a reason for OP to be inside the binary directory for the application in order to use it?

Why was the binary writeable in the first place?

If the binary was not normally writeable but the user was privileged, was it necessary to use a privileged user for this operation?

You could probably create a pretty extensive list of failures that led to this issue. I think the author honed in on the one that made the most sense to himself and missed the forest for the tree.


So if someone grabs your hair during a fight, are you going to go bald the rest of your life? Just paste it somewhere besides a terminal. I swear, security people have run away with everyone's good sense.

There's a point of diminishing returns where running with something that can cause a problem is completely practicable and justifiable. We don't need the nteenth "Shell that protects you from malicious paste" functionality. Just use root judiciously. If you can't be comfortable running as root and keeping yourself out of trouble, then you really don't know enough to use the machine safely.

You must be 10% smarter than the piece of equipment. No amount of good natured or well-intentioned "protect you from yourself" coding will obviate you of the need to know what you are doing, the limitations of the machine, and the limitations of the program you're using. In fact, all it does is increase the bar for how many things worth of minutiae you have to account for.


AFAIK Bourne shell (and Bash) defaults to $ for regular users. C shell (and tcsh) use %.


Bash, via GNU Readline, has an option that sidesteps this issue:

  enable-bracketed-paste (On)
       When  set  to On, readline will configure the terminal in a way
       that will enable it to insert each paste into the editing  buf‐
       fer  as a single string of characters, instead of treating each
       character as if it had been read from the keyboard.   This  can
       prevent  pasted  characters  from  being interpreted as editing
       commands.
Effectively it means that even if you paste garbage into the terminal you still have to hit enter before the command is interpreted.


This is the real solution! I think every shell supports "safe paste" in some way. For example, here's something for Zsh: https://github.com/ohmyzsh/ohmyzsh/blob/master/plugins/safe-...

This works great in combination with another advanced feature, "edit command" or "edit and execute command". Once you've pasted a command into the terminal, even a multiline command with safe paste, you can have the shell open your $EDITOR to edit the command, and automatically put the result right back into the shell (or just run it). This is available in Bash by default as ctrl-x ctrl-e.

(And as someone else pointed out below, if you don't want to enable safe paste, you can open the editor first on a blank command line and paste into that. But really we should all enable safe paste.)


Thank you, I think I've accidentally activated this mode without knowing _or wanting_ it when muscle memory for copy/paste happens while using a windows workstation but E.G. putty. Now I know it's a mode and that ctrl-e can undo it.


It should be enabled by default, so it would truly help.

By the way, doesn't this solve the sudo issue too? That where a password prompt swallows the rest of the pasted lines.


TIL:

  man readline
is a gold mine!


This won’t help for the kind of clueless blind-paste people who run into this issue in the first place - they don’t know what they are doing, is the actual problem. They’ll just paste whatever, hit enter, and then ask for support because nothing works :)


I've been a UNIX admin & developer for 25 years. I still on occasion accidentally paste the wrong text into the terminal.

(Admittedly, I think it only ever happens at home now, because everything I do on a work system scares the hell out of me.)


The classic copy-pasteable prompt (for true graybeards) is simply

        PS1='; '
If you want some more information, the trick is this:

        PS1=': stuff ; '
where "stuff" is whatever string you want to show (without redirection characters). This works because the colon is the "true" executable that ignores all its arguments, and the semicolon introduces your command that can thus be pasted along the whole line.


The ";" prompt was specific the "es" and "rc" shells, and not really used with any other more common ones, so most graybeards wouldn't have used that as PS1. Also, to be a graybeard and have copy/paste, you're talking about a very expensive computer with a mouse, like a Sun workstation. And all of those csh users from the late 1980s couldn't have, since it would cause a syntax error :-)


I remember independently inventing the ": foo;" prompt, and using it with Bash, in the late 90s. My beard is gray now.

It's not really practical because there are all sorts of values of "foo" which will make Bash choke when it tries to evaluate the string. Backticks and parentheses, for example, will cause problems, as will newlines (which NB may even occur in filenames, along with other problematic characters!). So the "foo" string typically needs to be sanitized using an external command: https://tldp.org/HOWTO/Bash-Prompt-HOWTO/x279.html

Once you get to that point the idea no longer seems as elegant.


I just use

  hostname=; 
which seems to work out fine.

I don't think this trick is really intended for people who want fancy prompts, but I'm not one of them, so it's great for me :)


I don't have a beard but I did use c shell from about 1980-1988 when I realized I was an idiot.


Subtle greybeard update: ` :>/some/file ` still evaluates in shell, it will zero out a file (truncate) quick and dirty - the emphasis in enriquto's comment is still very important, do not include redirection chars.


You don't even need the ':'.

'>/some/file' works as well.


Parent's point was that starting your prompt with `:` isn't a guarantee that everything that follows is safe (to expand on the "without redirection characters" remark by the OP).


He did mention graybeards.


No beard but it would be grey...

A variant of this has been my PS1 since the 90s (yes, mostly on workstations with a GUI by then [Sun,NeXT,HPUX etc...]). Unfortunately bash doesn't like a lone ';' without something before it ("-bash: syntax error near unexpected token `;'") so I've had to use ':; ' with it (I like its use of readline, emacs user since Gosling's in the early 80s).

Triple-click, middle-click (for xterm and others that do that) is efficient and easy. The csh-inspired '!!' can work nicely too though.


I guess the most important message isn't even "don't paste things into the terminal". It's "don't use a terminal that pastes things automatically, or by some action you will do by mistake".

Or, more specifically, don't ever use the default behavior of putty in a laptop with a trackpad and a gesture enabled for left click. If you use putty, set copy and paste to something less random.


When pasting something to the terminal (especially if it's longer than one line or was copied from an untrusted source), I like this approach:

1. open your terminal emulator;

2. press Ctrl-X + Ctrl-E in a shell prompt;

3. it opens your $EDITOR, paste the command there, check it for anything unusual, then save and exit;

4. the shell runs whatever was in that script you saved.


Nice, thanks, learned something :)

Tip for Vi/Vim users: to exit without having the command run, exit the editor with failure; the command for that is is :cq in Vim. (Also works fine in git to cancel commits etc.)


Adding for emacs users, the kill-emacs command does the same. I don't think it has a shortcut by default, so it's M-x kill-emacs.


Always enable the option 'confirm paste' if available in an terminal emulator.


iTerm has great behavior here — it allows painless pasting of things without newlines, but prompts for pasteboard contents that contain newlines.


Fun trivia: this is the default character in the SUSE /etc/bash.bashrc prompt for the non-root user. There's a lot of code doing things, but it boils down to this one example of their prompt defaults:

    if test "$UID" = 0 ; then
        PS1="${HOST}:${PWD} # "
    else
        PS1="${USER}@${HOST}:${PWD}> "
    fi
A popular distro is shipping this out of the box.


When I moved from DOS to Unix, I quickly got used to the default prompt of "$" instead of DOS’s default ">". Whenever I see ">" in someone’s custom prompt I assume they are DOS or Windows people who couldn’t get used to change when they started using Unix-like systems.

(This is how normal DOS and Unix command prompts looked, for reference:)

    C:\DOS> chkdsk c:

    server$ vmstat


">" prompts aren't that uncommon outside of DOS, though

    $ telnet
    telnet> 

    $ irb
    irb(main):001:0>

    $ echo look at me i'm an unterminated string
    >
I guess python's ">>>" prompt is more robust against accidentally being interpreted as a redirection, at least.


Makes sense, but weirdly I did not follow that route. I started on Unix, then learned about DOS, did not use it much, but I did switch my Unix prompt to use '> ', because I liked it better. The default '$' has too much visual clutter for me. BUT, when I post snippets of shell commands on the web, I use '$ ' because most people are familiar with it.


No. That's what DOS prompts looked like for people who knew how to alter them from the default, or who used quite late versions of DOS. The default prompt in COMMAND was $n$g not $p$g .

   A>


I wrote “normal”, not ”default”. Almost every autoexec.bat file I saw in the wild contained “prompt $p$g”.


You didn't see very many, then. There were lots of people who didn't have that.


If you hit Control-X-E it will open whatever is set as $EDITOR in a temporary session you can paste your command in to. I'd recommend vim. You can even use vim to edit your command. Once you save and quit your command will be run.

The article mentions this but not the ^X^E shortcut.


Also `v` in command mode when your readline is in vi mode (set -o vi)


What I see here:

- Don't give everyone root permissions

- Make important files writable by root only. If regular users should not modify it, don't allow it

- And... yes, don't allow any special characters in your prompt for "paste random stuff in my shell and run it" ppl. To be honest, I'd even lock those ppl out of the system. You could insert an invisible, uncommon char in the default prompt, detect it, and log the user out (after sending you an email ;-))


It happens with automation running as root too even with sudo. Some automation will always have to run as root. Bad characters, unset variables, lack of tests in the script, lack of testing of the automation, lack of chaos testing. The most common clobbering of data I have seen was not so much even copy/pasting, but rather a lack of

  set -u
  set -e
  set -o pipefail
  set -o posix
in scripts used by automation. There is shorthand for this that I am intentionally leaving out. Every shell script used in automation should at least have set -u to avoid running if variables are unset. An entertaining example was:

  rm -Rf ${MYSQL_HOME}/bin
There are a couple problems with that line, but in this case they did not source their environment file correctly and wiped /bin on many servers.


I solved this problem in my own shell by checking the chunk of data being read from STDIN before automatically passing it from readline to the parser. If it contains multiple newlines then odds are it is pasted content so the shell prompts you with a warning that you're pasting multiline content. It even gives you an option of previewing the data you're pasting before running it in the shell.

I'm surprised more shells haven't adopted this approach because it was trivial to set up and almost never gets in the way except when you actually want it to. But I guess it couldn't be Bash or Zsh because odds are someone somewhere depends on Bash blindly accepting readline data as part of their production workflow: https://xkcd.com/1172/


In fish shell, with bob-the-fish theme[1] and powerline fonts, my prompt ends in ``. Gives a nice appearance, and definitely isn't a valid redirect.

Of course anyone who does manage to paste and execute code as root (or with sudo in the line) in a terminal without sanitizing it is careless, as long as their terminal doesn't have the stupid right-click-paste behavior. If it does, I agree with the author that it's just a bad terminal.

[1] https://github.com/oh-my-fish/theme-bobthefish


I wonder if anybody has modified their browser fonts with the powerline characters and can actually see the character you've written here. If those people are anywhere it'd be here. :)


It's a box in my browser, but when I echoed it on the command line it looked more like ▶


Weirdly, my Firefox displays it in the page as the Unicode box (E0B0), but if I right click and "Inspect Element", it shows the arrow character as it should be, as part of the span tag's content text.


I just tried clobbering with fish with a more default shell and it didn't happen.

  ~/r/pick (master)> ~/r/pick (master)> test
  No command 'master' found, did you mean:
  <snip>
 
  ~/r/pick (master)> cat test 
  Hello world


I felt smug in the knowledge that I use Emacs shell-mode, which treats the terminal as an editable text buffer and allows newlines to be copy/pasted, without executing anything until an explicit press of Return.

Then I remembered that shell-mode has a very similar problem, where pressing Return at some random point in the buffer will try to execute all of the following contents as a command! I might eventually try to mitigate this with some elisp, but my TODO list is already getting long ;)

PS: I actually use this multi-line input feature a lot, since it lets the command history store multiple lines together. For example, if I'm in some REPL, I'll often enter two lines at once: first to reload/refresh the inputs (e.g. `:r` in nix-repl, ghci, etc.) and second is the actual line of code I want to evaluate. That way, when I get the previous command by pressing C-up I get both lines, which ensures my expressions are always being evaluated in a clean, up-to-date environment. (Note that previous command is C-up, since up on its own will navigate around the buffer!)


The ": ... ; " is a good start, but you can also put in the $ or # before the semicolon using bash's "\$". This makes it especially protective if you copy+paste+oops as root ;-)

You have to have a space after the ":", so ": ", but you can colorize that bit in modern shells so they have a use. I color them green or red depending on the exit status of the prior command (using the PROMPT_COMMAND bash var). I also leave out the space after ";" and just colorize it to be invisible, but that's a personal quirk.

More importantly, you can use the PROMPT_COMMAND to filter out braindamage as you build the prompt, and thus prevent filenames - which can contain ">" - or something from producing a redirect in your PS1.


The prompt should end with a newline, so each command is on its own complete line, and you can select it by triple-clicking, without having to bother with character-by-character selection to skip the prompt. This works really well in Emacs shell mode.


TIL: You can use `echo $?` to get the last process's exit code.


this is actually the most useful thing to put in your prompt (much more than your username, the current directory and other redundant stuff), as in PS1='$?\$ '


I used to leave my prompt alone until recently, but was inspired by https://news.ycombinator.com/item?id=26059023 to at least conservatively raise my expectations.

Now my prompts start with the current UNIX time, coloured red if the previous exit code was non-zero, or green if it was zero. This gives me instant feedback on success/failure, and lets me retroactively see how long a command took (without having to re-run it with `time`).


wouldn't it be more useful to show the time difference? Or maybe only show it in case it is larger than 1 second?


I do that, if it's over 60 seconds - it's not as straightforward since you also need to use PROMPT_COMMAND, a debug trap, and a variable to store the start time: https://jakemccrary.com/blog/2015/05/03/put-the-last-command...


Duration and start time can both be useful, and the former can be calculated from the latter as needed. Plus it's easier to implement (stateless) and has consistent alignment (always 10 digits).

BTW here's the function I use:

``` showTime() { if [[ "$?" -eq 0 ]] then TIMECOLOR='\e[92m' else TIMECOLOR='\e[91m' fi echo -e "$TIMECOLOR$(date '+%s')\e[0m" } ```


Might be useful but I just spent half an hour trying everything at https://stackoverflow.com/questions/16715103/bash-prompt-wit... on a MacBook Pro and none of it worked.


That's because, as a MacOS user, you are probably using the Z shell, not the Bourne Again shell. Prompt syntax is specific to each individual shell program.

One cannot just blindly use a Stack Exchange Q&A that states that it is for "Linux" and "bash" on the Z shell on MacOS, or indeed on the Z shell on a Linux-based operating system for that matter. Or in the C shell. Or in the Korn shell. Or in the Watanabe shell.


Maybe you are not using bash. echo $SHELL to find out.


A good summary of the most frequent things like that: https://stackoverflow.com/a/5163260

(Although they're sometimes tricky to use without more careful consideration.. like everything with bash and other shells really..)


I like to use ▷ as my pointy-end-of-prompt character. Easy to spot on a small screen/window, but not overbearing, and no semantic meaning.


The problem that I see in your workflow is that you

A. cd into the "bin" directory instead of having it in your path.

B. The file permissions in bin allow you to write.


Oddly, it looks like it's also in their path since the command isn't prefixed with "./"


    set -o noclobber
... works wonders to avoid this.

Sure, one may have to think and replace instances of:

    foo > bar
with:

    foo | tee bar >/dev/null
or:

    rm -f bar ; foo > bar
... but the times the "noclobber" option has _helped_ me more than makes up for the times it's been a nuisance.


And to undo this in the current shell, because of said nuisance:

set +o noclobber

For some reason this is hard for me to remember, because of what the + and - signs have come to symbolize in more recent UI. set +o seems really backward to me, and unset, surprisingly, does not work.

I've commented this line out in all my .rc, because I've found it to be a nuisance without having bought me much. The better principle is do careful work as root, and don't give careless or junior people root. My root PS1 very 'l33t', look and despair:

export PS1="[\[\e[01:31m\u@h\[\e[m\] \W]# "


From the zsh manpage:

    >| word
    >! word
           Same as >, except that the file is truncated to 
           zero length if it exists, even if CLOBBER is unset.
Note: If you're a bash user the >| syntax is available, but not >!.


This was never an issue when shells were first invented, because there were no mice. You could not select a region of the screen with the mouse, so there were no cut-and-paste errors like these.

If I want repeat an earlier command, I use the up-arrow, or bang:

!a repeats the last command that began with an "a".


The computer mouse, in its current form, was invented half a decade before Unix itself was. This should be qualified with: there were no mice on the machines that ran Unix.


One could use some Unicode bracket character instead, e.g. U+276F: https://gist.github.com/claybridges/8f9d51a1dc365f2e64fa


Agree with the author, "do not run as root" is a great point. Prefix the required commands with sudo instead!

And even with "sudo", limit the exposure -- sometimes you can sudo to specific user/group instead of more general root.


I've run as root whenever possible for over a decade with 0 problems. I'm not going to relegate myself to constantly asking my own computer for permission to do anything. Same for UAC turned off in Windows, just don't run viruses.


Have you never accidentally bumped the middle mouse button while your mouse cursor was over a terminal?


I'm unsure if "protection against accidents" is that relevant for deciding to have a root terminal open or not. Even if the clipboard contained some destructive "delete everything" command plus an newline character, all the files I actually care about is in my home directory and can easily be wiped by my regular non-root user.


What about all the files other people using the machine care about?


Yeah, my reply naturally only works for personal computers, e.g. my laptop/desktop system where it's very unlikely anybody else but me will use it. For corporate servers where you have traceability requirements and such it's an entirely different question.


I did it, and the additional pain of all those bandaids proposed here it not worth it. I did crash servers, deleted clusters, botched up firewalls and routing by misclicks.

But any damage caused by this does not approach the pain caused by misguided attempts to avoid it.


typing 4 characters in front of a command and not using a '>' character in your prompt is pain?


Most commands I'd run would need sudo anyway so a mis-paste would probably run with sudo if I used it. Never had a mishap from a mispaste like that though, no.


I don't trust the terminal and myself so much that I when I rsync a remote folder to a local folder I use sshfs to mount that remote folder in read-only mode and rsync from that mount point rather than the remote folder.


Heh...back when I was taking an Intro to Linux class for my CS degree, the instructor was teaching us rsync, and he somehow accidentally nuked his entire home directory.

My lesson I took away from that was to not use rsync because it's too easy to get it wrong and lose a lot of data.


And today I shot myself in the foot: I had forgotten to mount the remote folder so rsync synced an empty folder to my work copy.

To-do: add a confirmation of a dry run to my rsync one-liner.


I use » instead which has been working well for me (zsh + alacritty on archlinux)


Is there any locale in which » is a shell metacharacter? Or is the set of shell metas fixed regardless of locale?


It was defined by POSIX [1] - of course anyone can extend POSIX functionality (and does), however I'm personally unaware of a locale which would break this specific convention / definition as it would almost assuredly break a lot of scripts in the world.

[1] https://pubs.opengroup.org/onlinepubs/009604499/utilities/xc...


It's a quoting character, so any environment that intends to use » semantically would probably not use it as a redirection character


Right, I was wondering if locales can influence the set of thing that behave as if they were ascii "


Juggling chainsaws is not a casual activity to be done lightly.

Using the root terminal is serious. Pasting junk in isn't to be taken lightly. Its evidence of carelessness. Don't blame the tool.


Cowards.

  export PS1='; rm -rf /home /var; '


OP might want to consider bracketed paste mode: https://cirw.in/blog/bracketed-paste


If you could configure the common shells (bash, zsh, fish) to run a custom command on submitted shell input before executing, you could build a heuristic function that would attempt to recognize when you were pasting in a prompt. Unfortunately, I'm not aware of such a capability, as it would be useful in a number of situations.

Another alternative is to put the octothorpe # at the beginning of your prompt - then you can keep your > at the end.


Fish just doesn't seem to process the redirected output to clobber the file when a command isn't found. If your prompt is a valid command it can clobber a binary but not otherwise, apparently.


I recall terminals (MacOS Terminal? definitely Konsole seems to) that prevent any paste from actually executing the command, even if it contains newlines. Doesn't that solve this problem?


The part "let's make sure that we are trying to execute the right command in its correct location" which then follows up by running pwd is strange. Your current working directory has nothing to do with where expdp is found unless you either prefix it with ./ -- which you didn't -- or put . in $PATH (which is generally not a great idea).


My takeaway is this: stop copy-pasting commands in the shell and use the superior history/command-line editing features of read line instead.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

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

Search: