And even with "sudo", limit the exposure -- sometimes you can sudo to specific user/group instead of more general root.
And even with "sudo", limit the exposure -- sometimes you can sudo to specific user/group instead of more general root.
Another alternative is to put the octothorpe # at the beginning of your prompt - then you can keep your > at the end.
if test "$UID" = 0 ; then
PS1="${HOST}:${PWD} # "
else
PS1="${USER}@${HOST}:${PWD}> "
fi
A popular distro is shipping this out of the box.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.
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.(Although they're sometimes tricky to use without more careful consideration.. like everything with bash and other shells really..)
[1] https://pubs.opengroup.org/onlinepubs/009604499/utilities/xc...
The article mentions this but not the ^X^E shortcut.
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.- 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 ;-))
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.
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.
(This is how normal DOS and Unix command prompts looked, for reference:)
C:\DOS> chkdsk c:
server$ vmstat
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.
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.
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.)
A. cd into the "bin" directory instead of having it in your path.
B. The file permissions in bin allow you to write.
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.But any damage caused by this does not approach the pain caused by misguided attempts to avoid it.
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]# "
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.
Obligatory XKCD: https://xkcd.com/1053/
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.
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.
\ @ and " are in their proper positions on a UK layout as well. :|
https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2F...
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/
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.
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!)
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!
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`).
If # isn't special, then the rest of the line is still parsed, so pasting '# foo || bar' or '# foo > baz' does do something.
If I want repeat an earlier command, I use the up-arrow, or bang:
!a repeats the last command that began with an "a".
$ 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.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.
(Admittedly, I think it only ever happens at home now, because everything I do on a work system scares the hell out of me.)
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.
* https://minnie.tuhs.org/pipermail/tuhs/2017-April/011286.htm...
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.
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.
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.
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.
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.
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.
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" } ```
man readline
is a gold mine!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...
To-do: add a confirmation of a dry run to my rsync one-liner.
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.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.
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.