7 ms·
Show HN: Sensible Bash: An attempt at saner Bash defaults
- onli 11y agoI like it. It is not a complete revamp of bash to something else (the zsh-comment below is not fitting), it just enables some comfort features bash readily supports. One can argue about the case-insensitivity, but I see no other option that could be controversial. Just a small collection of sane defaults.
- sapht 11y agoThis looks pretty sane overall. If you try this, be aware that it changes directory navigation, i.e. "Prepend cd to directory names automatically, so you can cd into directories just by typing their name", "Automatically correct spelling errors in arguments supplied to cd". I've tried these things and they drove me insane, so they're not good defaults for everyone.
- technimad 11y agoIn other words: making bash more like zsh
- jjawssd 11y agoCame here to say the exact same thing. Get zsh today. Give it a spin.
- aerique 11y agoOr fish, which is basically zsh with sane defaults.
- burke 11y agoAnd a completely incompatible non-POSIX syntax, which sounds great in theory but isn't nearly enough better to justify the departure IMHO.
- massysett 11y agoWhy does compatibility matter? If you have a script written for sh or bash it will just run using that interpreter.
- xaduha 11y agoThere are http://www.commandlinefu.com http://www.commandlinefu.com and the like. I copy and paste stuff from the web into the shell occasionally, I'm sure everyone does. I do use fish, but it is annoying sometimes, it's missing the most basic stuff like backticks. So much so that I think I'm going to stop.
- waxjar 11y agoI'm sure you know this, but it's not missing that feature. It's just that the syntax is different.
- stormbeta 11y agoFor starters, any utilities based on sourcing won't work, such as nvm/rbenv/etc. That's technically true for zsh in cases, but it's far easier to port or add compatibility for zsh than fish.
- freddie_mercury 11y agoYou can use bass which solves this problem without porting the script to fish: https://github.com/edc/bass https://github.com/edc/bass
- SoMuchToGrok 11y agoMinus it being bash-compliant. Deal breaker for most.
- coldtea 11y agoOr bash, since it will be installed everywhere, you don't have to get it, and most scripts you'll find online will work on it.
- MikeKusold 11y agoThis is a non-issue. The `!#/bin/bash` at the top of scripts will tell the interpreter which shell to run. And any one liner I've found online for bash has also worked on zsh (for me), but even if it didn't: `bash -c ls`
- aerique 11y agoYes exactly. Today I learned people actually write / use scripts without specifying the interpreter at the top of the script. This is like writing a Ruby script and expecting it to work when calling it with the Python interpreter.
- jlgaddis 11y agoYeah, it's actually not installed everywhere (e.g. FreeBSD).
- coldtea 11y agoAnywhere that matters. Besides, still more places than fish or zsh.
- wyldfire 11y agoI hear a lot about it -- could you give me your favorite 2-3 features that make you prefer it over bash?
- jjawssd 11y agoI am using zsh + prezto. https://github.com/sorin-ionescu/prezto https://github.com/sorin-ionescu/prezto Tab completion is extremely powerful. Even serious spelling mistakes are forgiven. The prompt is Git-aware and this provides a lot of helpful information which saves me from having to query the git cli. There are also plugins available for completion of other programs such as rake
- Symbiote 11y agoThree things I use regularly, even in scripts: 1) Glob qualifiers: ls *(.) will only match files, not directories, symlinks etc. ls **/*.jpg(.L-3000000on[1,5]) **/*.png(N) will match .jpg files in the current and all subdirectories, which are: . files L-3000000 with "length" (size) under 3MB on ordering them numerically [1,5] and only the first five plus any .png files, if they exist (N = it won't fail if they don't). I have some scripts with expressions this complicated, but day-to-day it's useful for finding empty files (L0) or excluding directories. "man zshexpn" and search "Glob Qualifiers". 2) Glob operators: ls DSC<100-200>.JPG matches files with names between DSC100.JPG to DSC200.JPG. setopt extended_glob ls *.java~*Test* matches all .java files, except those matching Test*. Same man page, search "Glob Operators". 3) Lazy for-loops (single command doesn't require do-done), and taking two variables: echo "A 1" > tempfile for i j in $(<tempfile); echo $i $j 4) Parameter expansion. > x=EXAMPLE.jpg > echo $x:r.png ${x:r:l}.png EXAMPLE.png example.png Interactively, shell history seems to be nicer, I use a couple of global aliases (alias -g L='| less'), and the completion system completes everything you can possibly think of, like usernames, hostnames, remote filenames, HTTP URLs, processes (for kill)...
- mryan 11y agoGreat list - I didn't know about glob operators. That glob negation is going to be very handy. Re number 2: That works in plain old Bash too: ls DSC{100..200}.jpg
- scrollaway 11y agoSpeaking of zsh, here's my zshrc file: https://github.com/jleclanche/dotfiles https://github.com/jleclanche/dotfiles Sane defaults, useful aliases, no dependencies and easy to expand upon. I made it mostly to give either a sensible default rc file to extend, or just a general high quality prompt.
- TallGuyShort 11y agoI'm a big fan of zsh. It doesn't seem to be solely focused on just "doing what you mean", which some of these tweaks seem aimed at; it seems aimed more at correctness. e.g., it would allow you to pass * .txt into a command if * .txt doesn't match anything. Bash will just assume I mean literally '* .txt' so you get different behaviour depending on whether or not there's a wildcard match. zsh has taught me the good habit of always using \* when I don't explicitly want shell expansion. edit: spaces add after asterisks to avoid formatting weirdness
- ridiculous_fish 11y agoHeh, fish shell contributors had a long discussion of failed wildcard expansions at https://github.com/fish-shell/fish-shell/issues/2394 https://github.com/fish-shell/fish-shell/issues/2394 . We all pretty much agreed that bash's passglob behavior is really bad. zsh's default is much better. Though to be fair, bash-style passglob behavior can be enabled in zsh by setting NO_NOMATCH. zsh is still zsh, after all. There's still plenty more wildcard nuttiness. A favorite is to execute a bare *: zsh will try to execute the first file, passing the other files as arguments!
- otobrglez 11y agoHey guys! If you are interested in "different" shells and REPLs I suggest you check out Ammonite-REPL / Ammonite-Shell -http://www.lihaoyi.com/Ammonite/ http://www.lihaoyi.com/Ammonite/ It's written in Scala and well. It looks ql. :)
- rout39574 11y agoMay be an old-fart prejudice, but my eyes cross to think that 'dash and underline are equivalent' might be a desired thing. Making bash be clever seems like a pile of pitfalls. To each their own.
- bpchaps 11y agoYeah, I don't get this one, either. This seems far away from sane. What's the rationality behind it?
- mrzool 11y agoI don't have any file or folder name starting with a dash, while underscores are pretty common. Treating dashes and underscores as equivalents saves you one keystroke (i.e. you can type `cd -folder<tab>` instead of `cd _folder<tab>`).
- wyldfire 11y agoYou mean it saves you one edit in the case where you've mistyped the directory name? Otherwise it seems like no keystrokes are saved among the two you show. EDIT: groan, ok, you win. Net -1 keystroke for most keyboards.
- mrzool 11y agoThe shift press doesn't count as keystroke? :)
- jsprogrammer 11y agoMost keyboards only emit an underscore while a shift button is depressed.
- bpchaps 11y agoIs this really the reason? One keystroke? That just borders on bloat... Just put "set -o vi" if you want to remove keystrokes, which this doesn't include.
- ymse 11y agoMinor nitpick: why is the session history larger than the maximum file size? It always annoyed me that HISTTIMEFORMAT is not set by default. Without it, log entries are simply not timestamped at all. The readline tweaks were news to me, thanks.
- LukeShu 11y agoHISTFILESIZE is kind of a misnomer. It's the maximum number of lines in HISTFILE, where HISTSIZE is the maximum number of commands. If you have HISTTIMEFORMAT set, then each command gets at least 2 lines, plus the possibility of multi-line commands.
- wyldfire 11y ago> Prepend cd to directory names automatically, so you can cd into directories just by typing their name; I'm pretty sure this is a solution to a problem I don't have today. > Treat hyphens and underscores as equivalent; > Automatically correct spelling errors during tab-completion; I'm terrified to put this in my shell. Then again, it's not all-or-nothing: > cherry-pick the options you like most ... everything is open for discussion
- jimminy 11y agoPrepending cd for directory names would be kind of bad for me. I tend to create local scripts to initialize project environments using their root directory name. So the automatic prepending would make the action ambiguous as a command.
- hamidnazari 11y agoThat's the first thing I disable every time I set up oh-my-zsh on a new box. I think it should not be a default behaviour and should only be enabled if needed.
- hornetblack 11y ago> > Automatically correct spelling errors during tab-completion; > I'm terrified to put this in my shell. I had it in once (it's one the options in zsh setup) Once I was cleaning my home directory: rm -rf tec<Tab> rm -rf IdeaProjects<Ret> I'm a bit too quick to press enter after tab. So i deleted the wrong folder. I do still have it auto correct case. So `doc<Tab> -> Documents`
- Gratsby 11y agoSensible Bash... like Fish or Z Shell?
- ChrisArgyle 11y agoSome great ideas here--a lot of them solve problems I've personally had with bash over the past 15 years--but plenty of these feel like solutions in search of problems. I'm tempted to post my own commentary but I'd probably make the same mistakes. What would be really fantastic is a usability study of bash to see what the common pain points are.
- rejap 11y agoa lot of this stuff is present in cygwin but by default commented out. Something what made me more productive is a cd_func: out of .bashrc: function cd_func This function defines a 'cd' replacement function capable of keeping, displaying and accessing history of visited directories, up to 10 entries. To use it, uncomment it, source this file and try 'cd --'. acd_func 1.0.5, 10-nov-2004 Petar Marinov, http:/geocities.com/h2428, this is public domain
- thom_nic 11y agoI feel like discussion of 'sensible bash defaults' is incomplete without mention of .inputrc. My most "can't live without it" setting for bash is actually an .inputrc setting: # From http://www.ukuug.org/events/linux2003/papers/bash_tips/ # Incremental searching with Up and Down is configured in .inputrc "\e[A": history-search-backward "\e[B": history-search-forward ... so if I type `ssh <up arrow>` I get the last command that started with `ssh`, not the last command I ran. oh-my-zsh thankfully does this by default as well. But I still use my .inputrc on server boxen where I don't want/need to install a different default shell. Also worth noting that all of those `bind` commands in OP's script are actually .inputrc lines if you remove the `bind` and surrounding quotes.
- ajross 11y agoThis is why these things are so personal. I'd hate this. The up/down bindings are absolutely tied to specific command orders in my head. I need to know that "three commands back" is wherever I was in the sequence of commands that I'm repeating. If I'm trying to semantically query my history (for "ssh") in this case I'll use the ^R binding to incrementally search the history, or literally grep ~/.history for what I'm looking for. That's not to say that you're "wrong", just that calling these things "sensible defaults" is sort of missing the point. Nothing about them is sensible for everyone.
- omalsa04 11y agoIf you just press "up" without typing anything first then it works as you expect. I find ^R annoying if I've already started typing the command and then realise I can search the history (although that's probably configurable). Once you get used to it, the only downside of up/down history search is when you ever use a shell that doesn't do it and you feel lost.
- zo1 11y agoOn a standard Ubuntu install: If you press ^R after already typing part of what you're searching for, and then press a key (space, or more of the command you're searching for), then it'll switch to the history-search mode with that value pre-filled in.
- riquito 11y agoDoes anyone know if bashscript could be updated to allow spaces between assignment? I can't see how it would break existing programs (but I'm sure there's a catch) and scripts would be much cleaner (and less of an headache).
- opejn 11y agoA breaking example might be trying to find lines containing an "=" in a file: grep = my_file Also a problem is the syntax for running a program with environment assignments that apply only to the program: env1=foo env2=bar env3= my_program Note that under POSIX rules, "env3" here is assigned a zero-length string. Making these sorts of assignments work with spaces around the equal signs would open up a can of worms.
- burgerdev 11y agoMost of these are included in /usr/bin/fish :)
- heydonovan 11y agoCame here to say this! Got tired of the little quirks, and never looked back.
- alphapapa 11y agoYep, for interactive use, Fish is fantastic. Bash is still a better choice for most shell scripting though. Also recommend using something like Percol or fzf for filter-as-you-type command history.
- modeless 11y agoThese history settings should clearly be the real defaults. I wonder how difficult it would be to get them changed upstream? Upstreaming would also allow improvements, for example PROMPT_COMMAND='history -a' doesn't update history until the next prompt is displayed. If you close your terminal while a program is running then the last command entered is not saved.
- justin_vanw 11y agoI thought 'sensible bash' was called zsh. Just kidding, but not really, zsh is great and basically compatible with Bash, check it out.
- LASR 11y agoOr just use fish. Why is this even a conversation in 2016?
- dlitz 11y agoIt would be nice if bash had a more discoverable version of the 'help' command for new users. Right now, someone (say, a bright 12-year-old) who opens up a terminal for the very first time and types "help" is greeted with this lovely mess: compgen [-abcdefgjksuv] [-o option] > return [n] complete [-abcdefgjksuv] [-pr] [-DE] > select NAME [in WORDS ... ;] do COMM> compopt [-o|+o option] [-DE] [name ..> set [-abefhkmnptuvxBCHP] [-o option-> continue [n] shift [n] coproc [NAME] command [redirections] shopt [-pqsu] [-o] [optname ...] declare [-aAfFgilnrtux] [-p] [name[=v> source filename [arguments] dirs [-clpv] [+N] [-N] suspend [-f] disown [-h] [-ar] [jobspec ...] test [expr] echo [-neE] [arg ...] time [-p] pipeline enable [-a] [-dnps] [-f filename] [na> times eval [arg ...] trap [-lp] [[arg] signal_spec ...] exec [-cl] [-a name] [command [argume> true exit [n] type [-afptP] name [name ...] export [-fn] [name[=value] ...] or ex> typeset [-aAfFgilrtux] [-p] name[=va> false ulimit [-SHabcdefilmnpqrstuvxT] [lim> fc [-e ename] [-lnr] [first] [last] o> umask [-p] [-S] [mode] fg [job_spec] unalias [-a] name [name ...] for NAME [in WORDS ... ] ; do COMMAND> unset [-f] [-v] [-n] [name ...] for (( exp1; exp2; exp3 )); do COMMAN> until COMMANDS; do COMMANDS; done function name { COMMANDS ; } or name > variables - Names and meanings of so> getopts optstring name [arg] wait [-n] [id ...] hash [-lr] [-p pathname] [-dt] [name > while COMMANDS; do COMMANDS; done help [-dms] [pattern ...] { COMMANDS ; } user@host:~$