15 ms·
Do not use redirection characters in your shell prompt
- theamk 6y agoAgree 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.
- jimmaswell 6y agoI'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.
- aidenn0 6y agoHave you never accidentally bumped the middle mouse button while your mouse cursor was over a terminal?
- Aransentin 6y agoI'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.
- aidenn0 6y agoWhat about all the files other people using the machine care about?
- Aransentin 6y agoYeah, 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.
- lstodd 6y agoI 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.
- aidenn0 6y agotyping 4 characters in front of a command and not using a '>' character in your prompt is pain?
- jimmaswell 6y agoMost 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.
- hebz0rl 6y agoI use » instead which has been working well for me (zsh + alacritty on archlinux)
- jeffbee 6y agoIs there any locale in which » is a shell metacharacter? Or is the set of shell metas fixed regardless of locale?
- stonesweep 6y agoIt 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/xcu_chap02.html https://pubs.opengroup.org/onlinepubs/009604499/utilities/xc...
- kaslai 6y agoIt's a quoting character, so any environment that intends to use » semantically would probably not use it as a redirection character
- jeffbee 6y agoRight, I was wondering if locales can influence the set of thing that behave as if they were ascii "
- jandrese 6y agoThis 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.
- eythian 6y agoI 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."
- rcarmo 6y agoYeah. 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.
- minitoar 6y agoWow I never heard that! I always thought it was just some arbitrary convention I guess.
- rcarmo 6y agoI _think_ it started becoming commonplace around the early days of X11, although to be fair # and $ are neighbors on pretty much any keyboard layout.
- alpaca128 6y ago> # and $ are neighbors on pretty much any keyboard layout Aside from ISO QWERTY, AZERTY and at least 3 different QWERTZ variants, among others.
- jodrellblank 6y agoNot 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%2Fquietpc.co.uk%2Fimages%2Fproducts%2Fmatias-quiet-pro-keyboards-10-large.jpg&f=1&nofb=1 https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2F...
- scudd 6y agoTIL: You can use `echo $?` to get the last process's exit code.
- enriquto 6y agothis 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='$?\$ '
- chriswarbo 6y agoI used to leave my prompt alone until recently, but was inspired by https://news.ycombinator.com/item?id=26059023 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`).
- enriquto 6y agowouldn't it be more useful to show the time difference? Or maybe only show it in case it is larger than 1 second?
- Izkata 6y agoI 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-commands-run-time-in-your-bash-prompt/ https://jakemccrary.com/blog/2015/05/03/put-the-last-command...
- chriswarbo 6y agoDuration 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" } ```
- fouric 6y agoIf 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.
- vlovich123 6y agoI 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?
- Symmetry 6y agoFish 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.
- stonesweep 6y agoFun 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.
- enriquto 6y agoThe 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.
- stonesweep 6y agoSubtle 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.
- diffuse_l 6y agoYou don't even need the ':'. '>/some/file' works as well.
- erlkonig 6y agoThe ";" 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 :-)
- piger 6y agoOP might want to consider bracketed paste mode: https://cirw.in/blog/bracketed-paste https://cirw.in/blog/bracketed-paste
- zests 6y agoIf 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.
- mjsir911 6y agoAlso `v` in command mode when your readline is in vi mode (set -o vi)
- RVuRnvbM2e 6y agoBash, 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.
- loloquwowndueo 6y agoThis 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 :)
- macintux 6y agoI'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.)
- oconnor663 6y agoThis 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-paste/safe-paste.plugin.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.)
- KETpXDDzR 6y agoWhat 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 ;-))
- LinuxBender 6y agoIt 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.
- erlkonig 6y agoThe ": ... ; " 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.
- SAI_Peregrinus 6y agoIn 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 https://github.com/oh-my-fish/theme-bobthefish
- rcoveson 6y agoI 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. :)
- jessaustin 6y agoIt's a box in my browser, but when I echoed it on the command line it looked more like ▶
- sundarurfriend 6y agoWeirdly, 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.
- Symmetry 6y agoI 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
- teddyh 6y agoWhen 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
- bxparks 6y agoMakes 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.
- ben0x539 6y ago">" 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.
- JdeBP 6y agoNo. 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>
- marcosdumay 6y agoI 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.
- stelliosk 6y agoAlways enable the option 'confirm paste' if available in an terminal emulator.
- pcl 6y agoiTerm has great behavior here — it allows painless pasting of things without newlines, but prompts for pasteboard contents that contain newlines.
- scaladev 6y agoWhen 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.
- kzrdude 6y agoNice, 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.)
- marcosdumay 6y agoAdding 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.
- throwawayffffas 6y agoThe 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.
- Izkata 6y agoOddly, it looks like it's also in their path since the command isn't prefixed with "./"
- mfontani 6y agoset -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.
- devchix 6y agoAnd 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]# "
- JNRowe 6y agoFrom 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 >!.
- unop 6y agoMy takeaway is this: stop copy-pasting commands in the shell and use the superior history/command-line editing features of read line instead.
- twic 6y agoCowards. export PS1='; rm -rf /home /var; '
- hnlmorg 6y agoI 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/ https://xkcd.com/1172/
- deleted 6y ago[deleted]
- johnchristopher 6y agoI 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.
- johnchristopher 6y agoAnd 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.
- Sohcahtoa82 6y agoHeh...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.
- chriswarbo 6y agoI 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!)
- alejohausner 6y agoThis 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".
- JdeBP 6y agoThe 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.
- amelius 6y agoIt's 2021. Do not use software that doesn't have an "undo" functionality.
- layer8 6y agoOne could use some Unicode bracket character instead, e.g. U+276F: https://gist.github.com/claybridges/8f9d51a1dc365f2e64fa https://gist.github.com/claybridges/8f9d51a1dc365f2e64fa
- jachee 6y agoI 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.
- DonHopkins 6y agoThe 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.
- das4119 6y agoJuggling 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.
- jhugo 6y agoThe 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).