Things I Wish I'd Known About Bash - <AUTHOR> https://zwischenzugs.com/2018/01/06/ten-things-i-wish-id-known-about-bash/ <comment><USER3> Using readline is a great thing to know about too.

My favourite little-known readline command is operate-and-get-next:

[https://www.gnu.org/software/bash/manual/html_node/Miscellan...](https://www.gnu.org/software/bash/manual/html_node/Miscellaneous- Commands.html)

You can use it to search back in history with C-r and then execute that command with C-o and keep pressing C-o to execute the commands that followed that one in history. Very helpful for executing a whole block of history.

For some reason, this documentation is hard to find! It's not here, for example:

[http://readline.kablamo.org/emacs.html](http://readline.kablamo.org/emacs.html)

I'm a bit saddened when readline replacements don't implement C-o. For example, the Python REPLs don't have it.

<comment><USER4> I've overridden ctrl-r in my local Bash to search with fzf[0] and I'm using my history so much more now.

Didn't know about ctrl-o though, it sounds great! I hope that my ctrl-r override doesn't somehow break it.

[0]: [https://github.com/junegunn/fzf](https://github.com/junegunn/fzf)

E: Fixed link.

<comment><USER5> That link is a 404 for me?

<comment><USER6> It had a trailing >, [https://github.com/junegunn/fzf](https://github.com/junegunn/fzf)

</comment></comment></comment></comment><comment><USER7> I wrote a book on Bash too. The most important thing for anyone to know about Bash is that it's intended as a command language, not a general purpose scripting language. If it's longer than 10 lines, or if it uses two or more variables, you should probably have written it in something other than Bash.

<comment><USER8> Would you consider non-trivial install scripts as an exception to this general rule? I mean, you wouldn't write some install script in ruby or python, right?

<comment><USER9> I don't know why not?

At the least, rather than Bash, you might consider Perl as a default, lowest common denominator for scripts that need to run anywhere.

\- It's nearly as ubiquitous as bash.

\- It has approximately the same kinds of file/path operations built in.

\- It has reasonably good support for strings/regexes/etc. all built-in, so you don't have to call out to tools like sed/awk/grep all the time and hope that they are available and compatible across your target platforms.

\- It provides reasonably good arrays and hashes, which are horribly horrible in bash.[1]

\- You can use syscalls very easily if you really need to, but usually you don't.

[1] Of course, no language can save you from the file system disaster ([https://www.dwheeler.com/essays/fixing-unix-linux- filenames....](https://www.dwheeler.com/essays/fixing-unix-linux- filenames.html)), but being able to know that "foo bar" is a string instead of two array elements is a good start.

Mostly this all applies to Ruby or Python too, modulo perhaps the degree of ubiquity.

<comment><USER10> Great point about ubiquity.

Perl regexes are the best of breed that everyone else replicates — far better than "reasonably good."

The Perl erasure in this HN thread is startling.

<comment><USER11> > _" The Perl erasure in this HN thread is startling."_

 _" Erasure"_ to me implies some active effort to remove Perl from discourse. I don't see anything like that here: indeed, there are a number of positive mentions, and no negative ones I see. Granted, Python and Ruby are both mentioned more often, but none of those is at Perl's expense. Am I misunderstanding what you mean by 'erasure'?

<comment><USER10> This is what Perl is designed to be. Perl unlike the others is almost certain to be on any Unix or Linux installation. Several commenters leaving out Perl in discussions of the next step up from bash scripts is truly strange.

I suppose being ignored beats the typical _herp-derp_ anti-Perl bigotry, but I'd prefer all-around civility.

<comment><USER11> > _" Several commenters leaving out Perl in discussions of the next step up > from bash scripts is truly odd."_

I'm having a hard time following you here. Do you think that they're doing so for any other reason that Perl is no longer their go-to tool? There are communities where Perl is still used: PostgreSQL for example uses Perl for some of its scripting, as well as its build farm tool, in particular because of its portability on older systems.

That said, from what I've seen over the past 10 years or so, Perl hasn't had much of a presence in areas where a lot of computer work in tech is being done. For example, in cloud computing, or scientific computing, or machine learning, or web frameworks. Please don't read this to mean that Perl _couldn 't_ be or isn't being used in these cases or wouldn't be a better fit. (As an aside, I think Perl missed out a lot while a large portion of the community was focused on Perl 6: there's only so much energy in a community, and that absorbed on Perl 6 wasn't focusing on evangelism. But that's not something I'm interested in litigating here.) Or that there isn't something a bit frustrating in seeing the wheel reinvented time and time again. And so many examples on the web use bash as a common denominator. This puts Perl further out of mind if it's not already part of your everyday workflow. And how many developers today have come of age without seeing Perl in their everyday environments?

Consider the current forum. What's the percentage of front-page posts that are about Perl or tools where Perl is a part of the tool chain? It would be understandable for the people who frequent HN to not view Perl as their go-to. I don't consider it uncivil for people to neglect to mention some other language when it's not something they'd actually think of reaching for. It seems the solution would be to share examples of where Perl provides advantages, both in the comments here and in submissions to HN.

<comment><USER12> Well said, perl might be the theoretically best match in specifically this problem domain but the thing is there are only so many programming languages one can learn.

If i had to choose _only one_ of ruby/python or perl i would choose the former and it would be able to cover my base _both_ as glue-code and for more programs. Perl would maybe make the glue code a bit easier but instead i would be much less employable and have a much harder time finding other people who can read the glue. I'm not qualified to have an opinion on perls capabilities for other programs but i'm sure there are valid reasons most people prefer other alternatives.

</comment></comment></comment></comment></comment></comment></comment></comment><comment><USER13> Hang out in #bash on IRC Freenode and you will be a Bash jedi [http://mywiki.wooledge.org/BashFAQ](http://mywiki.wooledge.org/BashFAQ) best resource IMO for quick Bash syntax lookups as I always need to refer to the BashFaq to remember parameter expansion sub-string retrieval.

      parameter     result
      </comment><comment>-----   </comment><comment></comment><comment></comment><comment></comment><comment></comment><comment>
      $name         polish.ostrich.racing.champion
      ${name#*.}           ostrich.racing.champion
      ${name##*.}                         champion
      ${name%%.*}   polish
      ${name%.*}    polish.ostrich.racing

<comment><USER14> They are needlessly rude and mean at #bash. A bunch of scumbags, actually.

<comment><USER15> I think it's a result of constantly dealing with people who ask for help, receive good advice, and then ignore it

<comment><USER16> If that annoys then, they can always quit. Being rude in this situation is either a choice or lack of ability to cope with stress. Neither excuses being rude...

</comment></comment></comment></comment><comment><USER17> The sections on quoting and globbing suggest this author, though obviously trying to be helpful, isn't really knowledgeable enough to be writing such a guide.

I suggest reading this instead: [http://www.grymoire.com/Unix/Sh.html](http://www.grymoire.com/Unix/Sh.html)

Granted, it's about the Bourne shell, but since Bash, Korn, and every standard UNIX shell is supposed to be compatible with it, it's well worth learning.

And IMO, if you need more than what the Bourne shell provides, you should be using a proper programming language like Python instead.

</comment><comment><USER18> Bash has a huge number of little shortcuts that are difficult to learn. When one encounters a sequence of symbols like $(...), it is difficult to Google for its meaning. The reason shells nevertheless have these shortcuts is of course because they _are_ shells: from the commandline it can be very convenient to use shortcuts.

But, in my opinion, that's where it should stop: one shouldn't use a shell language for scripting. In scripts, it is simpler to use more verbose and clear constructs, because most editors are very powerful and provide shortcuts themselves.

<comment><USER19> Yeah, but why are you trying to use a search engine that cares less and less about exact matches, when there's a manual?

        >man bash
        /\$\(  # search pattern needs escaping
        ...
        value is evaluated as an arithmetic expression even if the $((...)) expansion is not used (see Arithmetic Expansion below).   Word  split‐
        ...
        n      # go to next match
        Command Substitution
           Command substitution allows the output of a command to replace the command name.  There are two forms:

                  $(command)
           or
                  `command`
        (detailed description follows)

I'm still in favor of using more verbose and especially more clear constructs, but not because they are easier for Google, but because they ideally hold enough information on their own that you don't even need to look it up to know what it does.

<comment><USER20> Man pages are specifically reference documents, not tutorials or guidebooks. To say one should use a man page is to say that one must completely digest the entirety of the tool prior to ever actually using it. That's just simply not feasible, nor should it be expected of anyone beyond trivial tools. Man pages simply don't provide the context for solving a problem like a guidebook or tutorial would, which is why there are so many sites that start with a problem and then explain the tools.

<comment><USER21> Which is why the parent advised to treat the man page like a reference document, by searching in it. Some man pages are just badly written and are indigestible even when searching for a specific thing, but in general, that approach works quite often.

<comment><USER22> Is there some trick to searching man pages that I don't know? Because my usual experience is:

      type man foo
      type /-p
      type n n n n n n n n n

as there are a bunch of matches like "...does bar when combined with -p..."

A presentation of man pages that used hypertext would make me a lot happier.

<comment><USER23> If foo has a Texinfo manual (GNU tools like bash usually do) then you can try `info foo` and search the index with i or I for -p. Texinfo manuals also have hyperlinks you can press enter on.

info is a greatly underused system and I'd recommend any *nix users to spend some time learning how to navigate it.

<comment><USER22> Thanks. Is there a good way to open that in a browser, rather than a console?

<comment><USER24> In general, the best way to read Info documentation is inside Emacs.

<comment><USER25> "If you are a bash newbie, you should read the bash manual. If you want proper search for the manual, you should use info. If you want proper use of info, you should use Emacs."

Kind of a deep rabbit hole, isn't it?

<comment><USER24> Not in this case; the bash manual is not in Info form, but a regular old-style Unix man page.

</comment></comment></comment></comment></comment></comment></comment></comment></comment></comment><comment><USER26> For me, the biggest gotcha in bash is whether or not a sub-process/shell will be invoked, which can affect things like mutable variables and the number of open file handles. For example:

        COUNT=0
        someCommand | while read -r LINE
                      do
                        COUNT=$(( COUNT + 1 ))
                      done
        echo "$COUNT"

This will always print `0`, since the `COUNT=` line will be run in a sub- process due to the pipe, and hence it can't mutate the outer-process's `COUNT` variable. The following will count as expected, since the `<()` causes `someCommand` to run in a sub-process instead:

        COUNT=0
        while read -r LINE
        do
          COUNT=$(( COUNT + 1 ))
        done < <(someCommand)
        echo "$COUNT"

Another issue I ran into is `$()` exit codes being ignored when spliced into strings. For example, if `someCommand` errors-out then so will this:

        set -e
        FOO=$(someCommand)
        BAR="pre $FOO post"

Yet this will fail silently:

        set -e
        BAR="pre $(someCommand) post"

<comment><USER27> I think I've run into the first issue you describe, and I'm having a hell of a time trying to understand it. Would you mind taking a look at my example and helping me out?

Consider the following:

      cd /tmp/
      echo -e "hello world\nhello world\n:)" >> hello.txt
      cat hello.txt

Outputs:

      hello world
      hello world
      :)

Then running

      bash -c 'sed s/"hello"/"hiiii"/ hello.txt | tee hello.txt'
      cat hello.txt

yields

      hiiii world
      hiiii world
      :)

Reseting to the original `hello.txt` and running

      ssh localhost -t 'cd /tmp && sed s/"hello"/"hiiii"/ hello.txt | tee hello.txt'
      cat hello.txt

yields an empty file.

Replacing the command with

      ssh localhost -t 'cd /tmp && sed s/"hello"/"hiiii"/ hello.txt >> hello.txt'

yields

      hello world
      hello world
      :)
      hiiii world
      hiiii world
      :)

I'm trying to figure this out so I can publish a script to set up a test env for a package I'm trying to publish, and somewhat stuck on this step...

<comment><USER28> You're using hello.txt as both an input file and an output file, which seems like it's just asking for race-condition problems.

What about using sed -i to make changes to the file, and not doing any bash redirection?

Alternatively, if the real problem is more complex than that, try using a different name for the output file and rename after it's finished.

</comment></comment></comment><comment><USER29> shellcheck ([https://www.shellcheck.net](https://www.shellcheck.net)) is an absolute godsend when writing Bash/POSIX sh scripts.

It catches so many errors that I think it's a must have in every programmer's toolbox. It even catches bash-isms when you are targeting POSIX sh. It saved me many many hours of grief trying to debug shell scripts I wrote and changed the way I write them for the better.

<comment><USER30> Targeting POSIX as much as possible is really important if you don't want to force Bash on people, especially with open-source public code. Many OSes don't have Bash in the default install, but many just assume that bash is available on all the target systems.

<comment><USER31> like which?

I'm hard pressed to think of a modern unix that doesn't include bash by default. Solaris maybe?

<comment><USER32> everything embedded - OpenWRT/LEDE uses busybox with ash - Android uses mksh? that only supports a subset of bash features. Every Debian/Ubuntu has ash as /bin/sh that only supports POSIX.

<comment><USER31> I'd argue that writing scripts for an embedded target for a regular server/workstation target are fundamentally different problems - <USER2> anything I'd write for those platforms would be targeted for them - not for general purpose unix.

Portability is only desirable, if you need portability - otherwise it frequently adds complexity for little return benefit.

</comment></comment></comment></comment></comment><comment><USER33>
        `` vs $()

I really appreciate authors who attack ambiguity or non-obvious equivalence in a subject head on. It's one of those aspects of explaining that takes to heart the perspective of the learner.

Another recent example I encountered is from the online book [http://neuralnetworksanddeeplearning.com](http://neuralnetworksanddeeplearning.com), there are some confusing ambiguities and plain misleading contradictions in NN terminologies, one being: multi-layer perceptions do not use perception neurons, these things can really screw with you while you're learning, especially the more subtle ones.

Some authors seem to have the ability to have full empathy for the novice while retaining expert knowledge and deep understanding by being able to both predict and answer relevant questions at the right point in an explanation at the right level of detail.

</comment><comment><USER34>
        rename -n 's/(.*)/new$1$2/' *

There's a chance this won't work on your system.

There are two incompatible versions of rename in the wild:

1) Perl one: [https://metacpan.org/pod/distribution/File- Rename/rename.PL](https://metacpan.org/pod/distribution/File-Rename/rename.PL)

2) from util linux: [http://man7.org/linux/man- pages/man1/rename.1.html](http://man7.org/linux/man-pages/man1/rename.1.html)

Debian (and dertivaties) ship the former; other Linux distros likely the latter.

<comment><USER35> I think this is not specific to the shell you are using, so it happens in bash, fish, ksh, zsh, and so on.

<comment><USER10> It's misleading because rename is a command that accepts regex arguments. The shell isn't doing anything more sophisticated with the quoted argument than passing it to rename as a positional parameter.

The shell of course does expand unquoted globs.

</comment></comment></comment><comment><USER36> Two important things missing:

1) This is a huge pet peeve of mine, but it kills me when my coworkers "bash" emacs and sing the praise of vim, then proceed to explain to me that ctrl-R in bash searches for the last command with a given pattern. They also often refuse to believe me that they're basically using emacs controls (because you know emacs' dirty). So, please, if you're in love with vim and use ksh or bash, learn about "set -o vi". Oh, and stop preaching!

2) "help xxx" for any xxx bash functionality, right there from the command line!

<comment><USER37> > they're basically using emacs controls

But not well implemented! You're supposed to be able to edit your search string, and I've never found a way.

<comment><USER38> Huh? Backspace works the same for me in Bash C-r as it does in Emacs C-r.

<comment><USER37> It never does anywhere for me. Good to know it's supposed to, though; maybe I've got something mapped weird, or the versions of the shell I'm using are old enough to be unwelcoming in this way, or I don't know what, but knowing it's not by design means there's a fix to be found for it. Thanks!

<comment><USER39> You should try hstr ([https://github.com/dvorka/hstr](https://github.com/dvorka/hstr)). It replaces CTRL-R with a full page interactive history search that really works.

Demo GIF here: [https://unix.stackexchange.com/a/375914](https://unix.stackexchange.com/a/375914)

<comment><USER36> If you use either vim or emacs, there's something to be said about using that knowledge for your command line history.

<comment><USER39> hstr has a vi mode.

</comment></comment></comment></comment></comment></comment></comment><comment><USER40> #0: If you're writing scripts that are destined for other users, use POSIX sh instead.

<comment><USER41> Do you know of any learning resources that are strictly POSIX sh instead of a specific shell? I'm looking to learn and it will be very helpful.

<comment><USER40> How about the standard?

[http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3...](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html)

</comment></comment></comment><comment><USER34>
        $ grep somestring file1 > /tmp/a
        $ grep somestring file2 > /tmp/b
        $ diff /tmp/a /tmp/b

You shouldn't do that, but not because it's not neat enough. /tmp is world- writable, so you might be writing to somebody else's file, or over a symlink that was set up by someone else. Use mktemp¹ for creating temporary files.

¹ [http://man7.org/linux/man- pages/man1/mktemp.1.html](http://man7.org/linux/man-pages/man1/mktemp.1.html)

<comment><USER42> Could you not do that with pipes instead, something like:

        $ diff <(grep somestring file1) <(grep somestring file2)

<comment><USER43> That's what the article is recommending.

</comment></comment></comment><comment><USER34> > if [ x$(grep not_there /dev/null) = 'x' ]

This is still wrong if the command can output spaces or meta-characters. You should quote the left operand, and then you don't need to prepend x:

if [ "$(grep not_there /dev/null)" = '' ]

<comment><USER30> Does the second only work with bash? Because IIRC it didn't work with FreeBSD's /bin/sh, you needed the initial x too.

<comment><USER34> No, this should work in any POSIX-compliant shell.

</comment></comment></comment><comment><USER44> The author mentions the substitution !:1-$ to insert all the arguments from the last command (like !$ substitutes the last argument and !! the full command). Note that !* does exactly the same thing, which is a bit easier to type/remember.

</comment><comment><USER45> ..it'd be nice if what was actually happening was explained of just statements like "[ is the original form for tests, and then [[ was introduced, which is more flexible and intuitive"

<comment><USER46> I recommend reading `man bash` for the section on Conditional Execution. It's remarkably readable and useful for man pages. It also cleanly explains the difference between the two.

</comment></comment><comment><USER47> +1 for the parts that are portable to Bourne shell/ksh/zsh.

-1000 for the parts that are specific to Bash. Stuff like that has been huge pain in my ass over the years. Some clever programmer uses some bash-ism and the build breaks on some ancient hardware that doesn't have bash.

I realize my complaint sounds like Henry Spencer's Ten Commandments and perhaps it feels outdated but trust me, you don't want to wade into thousands of lines of shell to track down why something doesn't work on the stupid AIX box.

<comment><USER48> > _Stuff like that has been huge pain in my ass over the years. Some clever > programmer uses some bash-ism and the build breaks on some ancient hardware > that doesn 't have bash._

Shouldn't the problem be the "ancient hardware that doesn't have bash" itself?

<comment><USER49> A brand new macbook pro will not have bash4.

<comment><USER4> The machine may not be ancient but I would still argue that the problem there is the ~10 year old version of Bash that Apple has decided to ship rather than the programmers that use features added to the shell within the last 10 years.

(I should add that I don't know what version High Sierra ships with but Sierra seemed to ship with 3.2.5x-ish which was 9 years old at the time.)

<comment><USER49> Well put it this way:

You can assume everyone has a modern bash, and make it the end users problem if they don't, or you can write portable shell scripts and know it will work.

Honestly the things you can't do in posix shell compared to bash border on "use a fully featured language" anyway.

<comment><USER4> Thing is that Bash is something you can assume to be reasonably widely available[0] — like Perl or Python — but I wouldn't expect to have to avoid any features from the last 10 years of either of those two. Sure, a certain grace period is to be expected but I think 10 years is way past that.

[0]: I know POSIX is supposed to be even more widely available but depending on what you're targeting then it may not be the best option [source: [https://en.wikipedia.org/wiki/POSIX#POSIX- oriented_operating...](https://en.wikipedia.org/wiki/POSIX#POSIX- oriented_operating_systems)].

<comment><USER49> Afaik neither perl or python are gpl3-only licensed.

Thats the blocker on macOS.

</comment></comment></comment></comment></comment></comment></comment><comment><USER24> If you use a thing a lot, you should probably invest some time in reading the manual for it.

The manual for bash consists of its Unix-style "man" page, and is therefore more of a reference than an instruction manual. I suggest using the _Advanced Bash-Scripting Guide_ ([http://tldp.org/guides.html#abs](http://tldp.org/guides.html#abs)).

</comment><comment><USER50> I really wonder why the author didn't just leave off the first two, and call it "Eight Things I...". Starting off with "backslash escapes can be confusing" and "/* doesn't just match things consisting of 0 or more slashes!" makes no sense if you're later going to skip over !! because it's "obvious".

</comment><comment><USER51> This is the most helpful bash diagram ever... why didn't I search for this before! [https://zwischenzugs.files.wordpress.com/2018/01/shell- start...](https://zwischenzugs.files.wordpress.com/2018/01/shell-startup- actual.png)

<comment><USER52> As given in the article, it's also the most annoying bash diagram ever...it needs an explanation of what the 7 different colors of arrows mean. All that was given is:

> It shows which scripts bash decides to run from the top, based on decisions > made about the context bash is running in (which decides the colour to > follow).

> So if you are in a local (non-remote), non-login, interactive shell (eg when > you run bash itself from the command line), you are on the 'green' line > [...]

With a bit of Googling I believe I found the origin of that diagram:

[https://blog.flowblok.id.au/2013-02/shell-startup- scripts.ht...](https://blog.flowblok.id.au/2013-02/shell-startup-scripts.html)

The author there explains how the colors work:

> Fortunately, I've read the man pages for you, and drawn a pretty diagram. To > read it, pick your shell, whether it's a login shell, whether it's > interactive, and follow the same colour through the diagram. When the arrows > split out to multiple files, it means that the shell will try to read each > one in turn (working left to right), and will use the first one it can read

<comment><USER53> This diagram is not entirely correct.

The remote bash startup order is further complicated by the existence of a compile time flag SSH_SOURCE_BASHRC. This flag determines if a remote non- interactive shell will load the ~/.bashrc file.

This flag is turned off by default and stays off in some distributions (like Archlinux), but is turned on in others (Debian, Fedora, ...) to replicate very old rsh behaviour.

</comment></comment></comment><comment><USER54> What was the surprising part about

        echo '*'
        echo "*"

? Both prints an asterisk. Is '*' some sort of BASH variable?

<comment><USER55> The asterisk * is a glob. Since double-quotes allow variables inside to be dereferenced rather than always quoting everything literally, presumably he was expecting that double-quotes might still allow globs to work rather than causing them to be quoted, when in fact all quotes will quote globs whether single or double. So he was expecting it might print out "a".

</comment></comment><comment><USER56>
        if [ x$(grep not_there /dev/null) = 'x' ]

See now, I never get why people do this. -z has existed forever.

<comment><USER57> Because it's acronym is very unclear. I think it stands for "zero", but I am not sure.

</comment></comment><comment><USER58> > !$ - I use this dozens of times a day. It repeats the last argument of the > last command.

Press ESC then full stop instead. Less key presses.

<comment><USER59> Fewer key presses, but doesn't work if you're using vi bindings.

<comment><USER28> ESC _ or M-_ does work in vi mode though (and does the same thing as ESC ./M-.). Search for "yank-last-arg" in the bash manual.

<comment><USER59> Thank you.

Went searching how to do it in Zsh as well when the Zshell Line Editor (zle) is configured in vi mode:

$ bindkey -M viins '\e.' insert-last-word

Will make ESC-. work from insert mode.

</comment></comment></comment></comment><comment><USER60> One of my favorite Bash patterns is the following. I call it 'feed the fish':

      . <(curl https://example.com/trusted.sh)

While it is _extremely dangerous_ I found it so easy to remember, that it stuck in my head. It downloads the script and executes it in the current shell. So if anything unexpected happens you probably have a real problem ;-)

Background: A few years ago I was writing a Bash based OS installer. So after booting from a live CD I had to fetch the installer and execute it, which lead me to using that pattern frequently.

While I love it, I can't stress enough how dangerous it is.

</comment><comment><USER61> If you "set -e", you probably also want to "set pipefail". By default, a pipeline returns the return value of the last element. pipefail means that if any element of the pipeline fails, then the pipeline as a whole will fail. I discovered this the hard way when I had:

make run-asan-test | c++filt

And even if the tests failed, the script would succeed.

</comment><comment><USER62> re 9) I feel better about always feeling at least slightly confused about what files are being sourced.

The graph included seems to originate from [https://blog.flowblok.id.au/2013-02/shell-startup- scripts.ht...](https://blog.flowblok.id.au/2013-02/shell-startup-scripts.html)

<comment><USER53> That graph is not entirely correct: [https://news.ycombinator.com/item?id=16088866](https://news.ycombinator.com/item?id=16088866)

</comment></comment><comment><USER63> I didn't see it mentioned, but I use it frequently so here is my tip. I'm not sure if it is bash specific (I just use it!).

Instead of typing !$ for the previous command's final argument, you can use the keyboard shortcut alt+. (alt+period). Pressing it multiple times will go to the last argument of previous commands. I use this quite a bit and found it easier than !$, because you can see which command it will be : )

I still don't always understand exactly what is happening with subprocesses vs subshells (chriswarbo's post is very useful in pointing out how wrinkly this can be), so I try and keep bash my usage simple.

</comment><comment><USER64> Blog states that author has 20 years of development experience.

Blog post suggests he knew little of basic shell scripting until recently.

Blog also reveals he is selling a book on shell scripting with Bash, "Learn Bash the Hard Way."

<comment><USER11> > _" Blog post suggests he knew little of basic shell scripting until > recently."_

I don't see how you could come to this conclusion based on the title. From the article, the author elaborates:

> _" Recently I wanted to deepen my understanding of bash by researching as > much of it as possible."_

There seems to be a lot of good commentary in this thread indicating that people are finding the post useful. There are points here that I have. Do you have specific disagreements with the post contents?

</comment></comment><comment><USER65> If you want all the args to the previous (or earlier) command just use ! _. (e.g. a common idiom for me is cat `!_ `). Or you tried a git mv out of habit but the dir isn't being managed by git: !gi: _

<comment><USER65> Oops that's the asterisk (star character) that HN interpreted as italics. In hacker news formattingnmy two examples are

      `!*` and !gi:*

</comment></comment><comment><USER66> This is why I use xonsh ([http://xon.sh](http://xon.sh)). It lets me use Python as a shell, and I don't have to remember too much awkward syntax.

</comment><comment><USER67> I wasted a lot of time on this one:

If you declare a local variable and set it in the same step e.g: local MYVAR = $(/bin/false) The return code you get is from the local declaration, not assigning a value to the variable. It can be quite confusing when you afterwards check the return code with $? and it returns 0. Avoid it by assigning the value in a seperate command.

</comment><comment><USER68> Interesting but from a modern perspective is not perl a better scripting language to learn.

I have never used bash scripts professionally i.e. as a language rather than a simple script with just a command in.

Like wise back in 87 or so I got trained in sed and I have only used it once since, and that was when I was playing around with early linix's (when it came on a huge number of floppys)

<comment><USER69> You have a terminal if you're on a Mac or Linux machine. It takes bash commands by default. Knowing perl is good, but knowing more bash is always good.

I hadn't known that <(echo "hi") is treated as a file with the contents of stdout, which simplifies commands that take files as arguments.

<comment><USER68> I meant using bash as a scripting language not as a shell.

</comment></comment></comment><comment><USER53> 9) The remote bash startup order is further complicated by the existence of a compile time flag SSH_SOURCE_BASHRC. This flag determines if a remote non- interactive shell will load the ~/.bashrc file.

This flag is turned off by default and stays off in some distributions (like Archlinux), but is turned on in others (Debian, Fedora, ...) to replicate very old rsh behaviour.

</comment><comment><USER70> I've been looking for something like <() for a long time. Thanks for sharing it!

Regarding :h, is it any different than just using dirname?

</comment><comment><USER71> Can someone explain :h as the article's description was not clear at all to me what was going on there.

<comment><USER72> Yeah, I couldn't make that work for me (on Linux or MacOS) .. although I'd love it if there were a way to quickly get 'just the directory' or 'just the filename' in bash with a shortcut, instead of having to resort to $(dirname blah) and so on .. I'm sure there is some way but :h doesn't look to be the shortcut as expected.

<comment><USER73> Assuming _blah_ is in a var named _name_ , you can use:

        dirname => "${name%/*}"
        basename => "${name##*/}"

Sadly you can't use it with !$ since it's not a variable. The closest you can do is:

        $ ls foo/bar/baz
        ls: foo/bar/baz: No such file or directory
        $ last=!$; echo "${last##*/}"
        baz
        $ echo "${last%/*}"
        foo/bar

</comment></comment></comment><comment><USER74> What is the best alternatives to bash for writing fairly large automation scripts? I have already looked at Python, Lua and Guile. The last two especially since I like using them and they have some sort of posix interfaces. I haven't looked at Perl 6.

<comment><USER10> Why didn't you consider Perl 5?

</comment></comment><comment><USER75> The trickiest part of Bash I know is that "$(command)" results in the truncation of the output of the command before the newline. It's both handy and damning depending on what you're trying to do.

<comment><USER76> I don't think that's correct, do you have an example? This works for me:

      $ var=$(echo $'a\nb')
      $ echo "$var"
      a
      b

<comment><USER75> Oh, I meant before the _trailing_ newlines, sorry for being unclear. Try using a\nb\n\n\n instead of a\nb and observing that the output doesn't change.

<comment><USER76> Ah, okay, got it. Yes, that can be surprising.

</comment></comment></comment></comment><comment><USER77> I haven't used the ! history for many years. It's simply easier and faster to use command line editing.

! was useful before command line editing; but not much since.

</comment><comment><USER78> Does fish-shell have an equivalent for '<()'?

<comment><USER79> [https://fishshell.com/docs/current/commands.html#psub](https://fishshell.com/docs/current/commands.html#psub)

<comment><USER78> Thanks a lot. Shells have so many features it's easy to miss one.

<comment><USER73> Watch out, there are some limitations to fish's psub preventing it to work as bash's >()

[https://github.com/fish-shell/fish- shell/issues/1786](https://github.com/fish-shell/fish-shell/issues/1786)

</comment></comment></comment></comment><comment><USER80> I didn't know a few of these, and I think I'll find `<()` specially useful.

</comment><comment><USER81> I understand "the hard way" is a commonly used phrase but it does seem a bit infringing on Zed Shaw's entire series Learn Code the Hard Way. Easily confusing. Other than that, good work

</comment><comment><USER82> bash or its minimal version such as ash is critical for embedded systems where python/perl etc are too fat.

</comment><comment><USER83> The thing I wished I had learned earlier is "quick and dirty assertions". If you write lots of functions in Bash, you quickly end up getting tripped up by cases where an argument is omitted and the function does something totally batshit given the missing (empty string) argument. Now, the canonical way to handle this is to put validators on your input, (and make sure those validators don't crash with cryptic errors if someone calling your function is using "set -u") like so:

      function() myfunc {
        local foo="${1:-}"
        if [ -z "$foo" ]; then
          echo "Invalid first parameter!" >&2
          return 127
        fi
        ...
      }

...but _man_ , that's time consuming when you have lots of parameters.

Instead, the quick and dirty way is to just "assert" via [parameter expansion]([https://www.gnu.org/software/bash/manual/html_node/Shell- Par...](https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter- Expansion.html)):

      function myfunc() {
        local foo="${1:?First parameter must be provided}"
        ...
      }

Much quicker, especially when throwing things together in a hurry. It has a gotcha, though: ":?" assertion doesn't cause a function to return early, it _shuts down the whole interpreter_ after outputting the error. So it's more like a true assert() statement than an input validator. If you'd only ever call your function in a subshell, this won't matter (because the subshell will exit early with a nonzero code, big deal), but otherwise it can be a nasty surprise to users when an argument-validation issue inside a function shuts the program down. Then again, the "return 127" in the first example would also shut the program down if someone was using "set -e".

...and while we're on the subject of "set -e", I think that the ["unofficial Bash strict mode"]([http://redsymbol.net/articles/unofficial-bash-strict- mode/](http://redsymbol.net/articles/unofficial-bash-strict-mode/)) (putting "set -euo pipefail" and "IFS=$'\n\t'" at the top of your scripts) has been a bigger bug-prevention/rapid development aide to me than anything else. To be clear, I think it's a means of detecting _some_ kinds of bugs. I've read Wooledge and others' objections to those patterns, especially "set -e", and agree with the point that this does not make your programs _objectively safer_ and shouldn't be counted on as a crutch. Then again, neither does a linter, but it still helps you detect and avoid some kinds of bugs, so why not use it?

<comment><USER84> I usually do something like that:

        [ -z "$1" ] && echo "Invalid first parameter!" >&2 && exit 127

as a precondition. I must admit that it's longer to write, but I can write a bunch of preconditions for my function then write the logic with an appeased mind

</comment></comment><comment><USER85> It's 2018 and we're still talking about writing non-trivial bash scripts?

<comment><USER86> It's 2018 and bash is still the most convenient language for an enormous number of tasks. Funny, that...

</comment></comment><comment><USER83> Something I wish people teaching intermediate or advanced Bash tricks would emphasize more is how to make your program compatible with other shells. With the rise of Zsh's popularity, and the switch to Dash for Ubuntu/some Debian derivatives, I see a lot of people repeating bashisms in code they share without the knowledge that a) their code may not work for an unexpectedly large number of people, and b) switching to compatible equivalents doesn't make their code worse or less performant in many/most cases.

The most common bashisms and ways to avoid them are:

\- Double brackets ([[) around conditions. Yes, I know that [ is a program (don't believe me? "which ["). That doesn't mean Bash uses it; it uses a builtin which is (almost) equivalent to [[ instead. Use that and your code will work in zsh/dash/all other POSIX shells. And while you're at it, stop using "which" as an authority for "is this a shell builtin or not?" [type()]([http://linuxcommand.org/lc3_man_pages/typeh.html](http://linuxcommand.org/lc3_man_pages/typeh.html)) is your friend.

\- When comparing strings for equality, use a single equals sign "=", not "==" (e.g. 'if [ "$foo" = "some string" ]'). I know it feels dirty if you've programmed in any other language, but it changes nothing about your code's behavior and makes it compatible with several other shells.

\- Don't use "function funcname()" syntax. It adds nothing over the basic "funcname()" syntax, but prevents your code running in many/most non-Bash shells. And consider putting your function-opening brace on a separate line (someone once told me that there are shells that won't accept any other function declaration style, but I've never seen one, so ymmv).

\- Don't use "local" if you need to interoperate with ksh. Abandoning "local" pollutes global namespaces, though, so your call.

\- Don't use substring expansion (e.g. extracting the 3rd-10th characters of a string via 'substr="${somevar:3:7}"'. That's not supported in many other shells. Alternatives include sed/awk/etc., or, if invoking external programs is absolutely unacceptable to you, something horrific like:

        substr()
        {
            local input="${1:?String is required}"
            local dist_from_start="${2:?Start position is required}"
            local dist_from_end="${3:-${#input}}" # Here, it's actually 'offset', not distance.
            local start_nulls=
            local end_nulls=

            dist_from_end=$(( 5 * (${#input} - ($dist_from_start + $dist_from_end)) ))
            dist_from_start=$(( 5 * $dist_from_start ))

            # Make a string of the regex for "any not null character" that "masks" the
            # characters in the input before the start point, and the characters after
            # the end of the substring. This is disgusting, and is only done because the
            # parameter expansion statements can't contain repetitions (e.g. [^\0]{5})
            # without the bash-only 'extglob' shell option.
            # The not-null character is used because it will never match in a shell
            # string.
            while true; do
                if [ "${#start_nulls}" -lt $dist_from_start ]; then
                    start_nulls="${start_nulls}[^\0]"
                elif [ "${#end_nulls}" -lt $dist_from_end ]; then
                    end_nulls="${end_nulls}[^\0]"
                else
                    break
                fi
            done

            input="${input#$start_nulls}"
            echo "${input%$end_nulls}"

        }

        substr "$@"

...actually, please never use that code. Ew.

Anyway, some more bashisms: [https://mywiki.wooledge.org/Bashism](https://mywiki.wooledge.org/Bashism)

</comment><comment><USER87> My take on the same topic:

\- use the unofficial strict mode: [http://redsymbol.net/articles/unofficial- bash-strict-mode/](http://redsymbol.net/articles/unofficial-bash-strict-mode/)

\- use parameter substitutions like ${foo#prefix}, ${foo%suffix} instead of invoking sed/awk

\- process substitution instead of named pipes: <(), >()

\- know the difference between an inline group {} and a subshell ()

\- use printf "%q" when passing variables to another shell (e.g. assembling a command locally and executing it via SSH)

<comment><USER25> Parameter substitution is far from intuitive. Every time I have to open one of my older shell scripts (>3 months ago), I'm thankful I wrote comments. Otherwise I'd have to man/google things again. I really wish they'd use function names or something, instead (sub, etc.).

<comment><USER87> My "mnemonic" is that # means _prefix_ , because every shell script _starts_ with a shebang too. From this I can deduce that ## means longest prefix, therefore % and %% means suffix.

</comment></comment></comment><comment><USER88> Damn it this boils down to RTFM, specifically the bash man page.

<comment><USER35> The real 'Learn bash the hard way' is to read the man page top to bottom every 6 months. Ye gods, I've read it so many times…

Also: lol at HN downvoting advice to read a tool's docs. Bash is terrible for a lot of reasons, but not because of its lack of informative documentation.

<comment><USER34> From the HN guidelines:

 _Please don 't comment about the voting on comments. It never does any good, and it makes boring reading._

<comment><USER35> I've read the guidelines; you can just downvote instead.

</comment></comment></comment></comment><comment><USER89> You shouldn't call your book 'learn X the hard way' if it isn't (also) freely available online if you ask me.</comment>


Why Employee Benefits Will Become Irrelevant - <AUTHOR> http://blogs.wsj.com/experts/2015/04/28/why-employee-benefits-will-become-irrelevant

<comment><USER2> >> giving way to an alternative where employers simply pay employees in full for services rendered, and employees are left to make their own decisions –for better or worse–about where and how to allocate those dollars for their needs.

That is so completely disingenuous. I think we can assume that blog writers at the WSJ are aware that wages have been stagnant for the majority of workers for over two decades, despite significant gains in productivity. So, really, what they meant to say was "giving way to an alternative where employers stop paying for benefits."

<comment><USER3> Currently employers get better rates for their benefits then an individual can on the open market. As such this will open the flood gates for even higher insurance premiums, seems like a wind fall to the insurance providers.

This is similar to the push away from pensions to 401k's in the 70's and 80's. It was supposed to be great for the individuals, more flexibility and control, can take it from job to job. Yet instead it was great for the financial services industry as they got to charge a higher service fees on their mutual funds to more people. The only people to lose out where the employees as the companies got reduced liabilities and payouts and the financial services sector go a large bump in service fees....

<comment><USER4> Could employees of different companies form a group that could get better rates? One of the problems with 401ks is that they are still related to your employer.

<comment><USER5> Yes - it's called a government. Pretty much all other countries already have such healthcare plans in place.

</comment></comment></comment></comment><comment><USER6> Author doesn't seem to have a clue about how benefits are taxed or that an employer can buy insurance or other benefits for 1000 people cheaper than any of the individuals can.

And are not Employer DC pensions better because that contributions on both sides are pre tax - let alone if you go in for sacrifice schemes where you can save the NI (social security) as well.

and this guys supposed to be a partner reads like some summer interns work to me

<comment><AUTHOR> > an employer can buy insurance or other benefits for 1000 people cheaper than > any of the individuals can.

Does that still hold true with the exchanges, which in large states supposedly pool millions of individuals?

<comment><USER7> I think so, and here is why it makes sense. Maintaining a steady employment is a pretty strong indicator of not having debilitating health problems and of having enough income to avoid poverty-driven health problems. The employee pool of a major corporation is probably a healthier pool than the one exchanges serve.

</comment></comment></comment><comment><USER8> Obviously I wish we lived in a world where health care wasn't coupled to employment, but I don't think the USA is adopting single payer any time soon so I don't really have high hopes.

However, one practical thing that I find infuriating is the 401k/IRA system. It's absurd to me that if your employer doesn't offer a 401k there's a whole category of tax advantaged retirement saving that's off limits to you, and you're stuck to the IRA contribution limits (and income limits).

</comment><comment><USER9> If done well, this could empower employees to decouple critical life needs (health insurance, retirement) from their employers. If done poorly (i.e. the non-employer options and tax benefits are not good), then it will just create a 2-tier system where you have a class of workers with great benefits, and those with terrible ones... Oh wait, that's what we have now, right?

<comment><USER10> Take away the tax incentives and let the market readjust. Imagine if employers provided our food directly and all the issues that would result from that. And then imagine what would happen if someone suggested ending that - we'd hear about how employers can buy food at a bulk discount, tax breaks, everyone's going to starve, etc.

Getting employers out of the health insurance game also conveniently dispenses with controversies like the HHS contraception mandate/Hobby Lobby etc.

</comment></comment><comment><USER11> Employee benefits will become irrelevant if and only if (1) the government removes the tax advantage of providing certain benefits to employees over providing the value of those benefits to employees in cash, and (2) the government resolves the market failures innate to certain types of insurance. The ACA went a long way to resolving (2) for health insurance, but similar forces are at play in the life insurance and disability insurance markets.

</comment><comment><USER12> > All it really means is that instead of an employer paying $X on behalf of an > employee for a certain benefit, the employer pays the employee that same > dollar amount and allows him/her to use the dollars as desired toward their > own selection of benefits, from retirement to health insurance and more.

This money is usually pre-tax. Let's say an office worker is making $80k/year + benefits and pays about 25% to taxes. If those benefits amount to $10k (feasible between 401k matching, insurance and other things) the employer needs to come up with an extra $3.33k to pay the employee to compensate for the tax owed on the extra income.

<comment><AUTHOR> "If you paid your health insurance premiums with your own after-tax money, they're deductible."

[http://healthinsurance.about.com/od/savingmoneyonhealthcare/...](http://healthinsurance.about.com/od/savingmoneyonhealthcare/fl/Is- Health-Insurance-Tax-Deductible.htm)

With a bunch of caveats, of course.

<comment><USER12> Ah, thanks. This would still be an issue with some other benefits unless they also are tax deductible or made tax deductible for individuals. My 5% matching on my 401(k), in particular, would be an issue without increasing the tax deduction limits on 401(k)s.

<comment><AUTHOR> It does make sense for the government to (a) allow for insurance premiums to be paid out of flexible spending accounts, (b) decouple pre-tax FSAs from employment and make them available to anybody.

Not sure why it's not part of the ACA, perhaps there are some unintended consequences (a) would cause.</comment></comment></comment></comment>


Lockitron exceeds $2,000,000 in reservations - <AUTHOR> https://lockitron.com/preorder?hn=true <comment><USER2> From <http://news.ycombinator.com/item?id=4699862> (also at the front page right now):

> _We funded the Lockitron guys back in the summer of '09—that's them at their > YC interview. A year after YC, they were still figuring out their idea. They > lived with the Wepay guys and one day the Wepays had a party for their > investors. By that point the Lockitrons were working on a product to lock > your door with an iPhone. They were able to impress one of the investors > with their prototype, and he asked to have 40 installed in some startup > offices he owned. The founders were psyched, but the commercial locks they > needed to use cost $500 a pop. They didn't have $20,000 to fulfill an order > that big. So they went around to the local locksmiths and scrapyards, buying > broken locks for about $10 each. They fixed them themselves and were able to > deliver on that order._

</comment><comment><USER3> It really pays to check how ones company name sounds in different languages. Because in some cases connotations could be not even funny :( For example in russian, lockitron sounds very similar to 'lohotron' which translates as con game, scam etc.

<comment><USER4> This is a non-issue.

Look at MongoDB.

If you want to say "You're a retard" in German you'd say "Du bist ein Mongo". Mongo being short for mongoloid and just as `politically incorrect` as retard is in the English speaking world. If anything the name made the product more memorable for me (and I use it almost every day now)

<comment><USER5> MongoDB is considered a complete joke by most who've programmed a distributed system.

So.... poor example.

<comment><USER6> For the first year or so I read about it, I though it was MnogoDB; as in, Mnogo Nukes. Woulda been a much better name.

</comment></comment></comment></comment><comment><USER7> This is bananas!

Please, someone who has reserved one ..

WHY do you need to open your deadbolt from anywhere other than your front door?

Do you often find yourself down the street / at work / in an overseas hotel with the need to open the deadbolt?

Don't you want to see who's there?

Don't you have a second lock built into the knob?

It's an interesting idea to control a mechanical object (lock) with an internet connection, but a deadbolt?

<comment><USER8> Founder bias here, but...

As someone who lives with three adult roommates who all have S.O.'s we have people in and out all the time.

As someone who lived by himself in college it was nice to know when the landlord came by.

As someone who runs a startup, it provides more benefit than a typical modern access control system without the $3000 price tag.

For American locks, the deadbolt provides most of the security. The handle can usually be loided and is kind of only useful if you're stepping out for a minute to grab the mail and want to shut the door behind you.

For letting someone in remotely, you usually have an idea that they're coming over first. If they were to show up unsolicited, you would likely call first.

<comment><USER9> Changing the lock probably violates your lease. And if you wanted to catch them entering your apartment without notice, something like a camera that creates readily identified evidence would be a better idea.

<comment><USER10> Isn't the whole point of this device that it works with your existing lock?

<comment><USER9> I wasn't sure if it can be configured to prohibit key access. How strong is it? If it can, it's unauthorized. If it can't, it's not keeping your landlord out.

<comment><USER10> He said he wanted to know when the landlord came, not keep him out. As far as I know, it won't even attempt to stop the key from opening the lock, but it will detect it.

</comment></comment></comment></comment></comment></comment><comment><USER11> @Lockitron, I recall the original story going: "We decided to host our own "Kickstarter" because investors did not seem interested and Kickstarter changed their policies."

I am curious, have you found that investors have changed their tune due to your successes so far?

<comment><USER8> I think you're conflating two stories. Eric from Pebble originally went on Kickstarter because of investor interest. We created our own crowd funding platform because Kickstarter changed their policies. Both stories are detailed here: [http://www.foundersatwork.com/1/post/2012/10/what-goes- wrong...](http://www.foundersatwork.com/1/post/2012/10/what-goes-wrong.html)

In both cases, investor interest is a barrier but the core problem seems to be 1) making something people want, 2) finding a platform to tell them it exists, and 3) being able to deliver it. Kickstarter is wonderful for 2).

</comment></comment><comment><USER12> Playing devil's advocate here, but what is the hype surrounding this lock?

I bought two 'aesthetic enough' keypad code locks from Home Depot and it' been serving me well since. It doesn't require my phone or launching an app from my phone (think bags of groceries in both hands and you forgot to preunlock), doesn't require Wi-Fi, and I can program temporary codes for Airbnb, etc. within seconds. The only draw back is lacking the option to increase 30 second autolock interval.

Add a keypad, make it as rugged as existing locks, place it in the Home Depot lock aisle beside the other 'uncool' locks and you have a disruptive winner.

<comment><USER13> Consider everyone who lives in an apartment who doesn't have the option of replacing their lock (and I wouldn't really want to anyway... I rather prefer the unchanged external appearance of this product).

IIRC, you can also easily deauthorize users, so it's also the cheapest way I can think of to retrofit something into being a shared space where you want to be able to control access going forward.

It's not the perfect lock solution for every use case, but it's a really cool utility for a lot of purposes.

<comment><USER7> So .. it stops physical keys from working?

<comment><USER14> No, it doesn't. Presumably the parent is describing a situation in which a temporary guest wouldn't receive a physical key at any time, but would have temporary access through the app.

</comment></comment></comment></comment><comment><USER15> As somebody whose enjoyed a keyless lock in a condo in Hawaii fairly recently I have few things to say.

* Keyless locks are great

* Depending on a phone is a very limiting requirement.

From my experience, it was a huge relief not to have to carry any valuables(such as a smartphone or keys) to the beach, because the door had a 4-digit-code lock device. If i had to carry a phone around with me, i would rather carry a set of keys.

Furthermore, if youre planning to use it for AirBnB and youre expecting that your tenants will have cell service, youre excluding international travellers who have just arrived in your town and may not have cell coverage with their international phones.

What I would like is a code-based lock that would allow me to reset the code remotely, to add multiple levels of codes, time-limited codes, etc. I would pay lockitron prices for it.

<comment><USER16> Lockitron is highly hackable, based on the video. A guy made bananas create tones based on pushing on them, and that set of tones opened the lock. You'd buy lockitron at that point as a way to interface with your lock in a more reliable way than whatever you could throw together.

Secondly, what do you need cell service for when communicating with a device via bluetooth? Or NFC? Or WiFi? No one's being excluded here except the unimaginative.

</comment></comment><comment><USER17> I wonder how strong the actuator is on the device. I know that most deadbolts don't line up all that great with the hole in the frame and require a lot of force to actually open and close. I'm sure the actuator is limited in how much force it can generate.

<comment><USER18> The Kwikset motorized deadbolts have tapered bolts to help compensate for poor alignment. I'm not sure why it's not more common with other locks.

</comment></comment><comment><USER19> How the device fits over the lock handle reminds me of another device I made to unlock a door. I had to get into a room to reset a router, however the lock was a deadbolt, and I didn't know how to pick it. Using a (heavily bent) coat hanger, I squeezed it through a crack in the top of the door, lowered it with twine until it grasped the lock handle, and then turned the device with some more twine (from under the door) and I was in.

Locks that open when the door handle (not a knob) is turned can also be opened relatively easily with coathangers from under the door. Make sure to consider all aspects when making secure systems!

</comment><comment><USER20> A lot of doubters when this was launched! Albeit not a jetpack, it's exciting to see the future slowly arrive!

<comment><USER21> If you see the comments here, there are still a LOT of doubters. Which surprises me a lot, this product is genius. With so much skepticism, if Lockitron was a stock, I would buy it.

</comment></comment><comment><USER22> I've been minimizing the stuff I carry in my pocket for a while now (for every day work).

The wallet was the first to go. Then I stopped carrying IDs (I use public transport). Now I'm down to my keys, my phone, a credit card, and a metro pass. The day when all I need is my phone is getting closer!

<comment><USER23> > Then I stopped carrying Ids

I assume you either a) don't drink or b) live in NYC.

<comment><USER22> Neither! Never got the acquired taste for alcohol. And I don't live in NYC - residing in Toronto atm.

</comment></comment></comment><comment><USER24> Interesting, but this seems similar to the Z-Wave[1]/Schlage Internet- controlled remote entry systems. I'm not sure what the additional value add is beyond an iPhone app.

Am I missing something?

[1] <http://www.z-wave.com/modules/ZwaveStart/>

<comment><USER25> For Z-wave, you still need a Z-wave gateway/controller, which can cost several hundred dollars. The Schlage gateway requires a monthly subscription.

</comment></comment><comment><USER26> Congratulations! Now if you can do the same thing for my gas oven, that's the next 2 mill!

<comment><USER27> Haha, completely agree with this sentiment. By far the most attractive thing about this for me is being able to check my phone and immediately assuage that "Oh shoot! Did I lock the front door?" feeling.

It's something I've been thinking about a solution to for a while. One of these days I'll get around to making a key cover with a simple mechanical display of which direction the key was last rotated. Cool idea, right?

</comment></comment><comment><USER28> You know, I was not impressed until I saw the guy playing the bananas to unlock his door. Now I must have one.

</comment><comment><USER29> This is all really great, but my ISP and router situation is not at 100% uptime and about once a week I need to reset them both. I wouldn't be able to rely on this completely :/

<comment><USER30> _"If you use an iPhone 4S or iPhone 5, you can enable Lockitron to sense when you walk up to the door and unlock for you using Bluetooth 4.0. We call it Sense."_

</comment></comment><comment><USER31> Lots of folks here "just don't get it" and lots of others think this is great. That is a good sign, startup-wise!

</comment><comment><USER32> Big congratulations!

</comment><comment><USER33> Congrats gents. :)

</comment><comment><USER34> Well deserved

</comment><comment><USER35> insane!

</comment><comment><USER36> Is this the same company that was on the Shark tank a few months ago?

<comment><USER37> It was <http://www.unikeytech.com/>

</comment></comment><comment><USER38> So now instead of carrying my keys around I get to carry a phone charger...terrific?

<comment><USER39> I always wonder about drive-by trolling. Suggestion to pg, make it so that accounts cannot post their first comment for 24hrs.

That said, this sort of complaint is not uncommon, I saw a lot of "Gee why not use a hidey hole? or a camo-rock?" and the answer is, of course, that for the use case these folks are targeting divulging the secret hiding space to a temporary renter means you need a new hiding space for the next one. So much easier to just delete their access code.

I didn't realize quite how much this industry needed to be disrupted until I went out and added fob based locks to our offices here at Blekko. What I _want_ is a self contained solution, I know I can hack one together with a few arduinos and RFID readers and a closet web server type app on a Raspberry pi, but nobody sells that. And some of the components are poorly documented (as it the general rule for "security" stuff it seems) for this reason alone I cheer on the Lockitron guys and look forward to their Enterprise product.

<comment><USER40> > _" Suggestion to pg, make it so that accounts cannot post their first > comment for 24hrs."_

Two problems with this approach:

1) if someone's post happens to make it big on HN and they discover us through their logs, they can't give feedback while their posts is still on the frontpage.

2) HN has a long tradition of throwaway accounts [0] being used to give valuable input in sensitive discussions (abuse, corruption, medical, financial, family/social, or legally dangerous.) A waiting period means those contributions won't be made, or at the very least, won't be seen by the majority of readers.

The price of getting rid of drive-by trolling is that we lose these contributions. Seems better to just downvote or flag the trolls, and keep the really excellent stuff.

[0] There are some real gems among [http://www.hnsearch.com/search#request/all&q=throwaway&#...</a>

<comment><USER41> In this particular case, keeping track of the similarity between posts might have helped. There's no legitimate reason to post the exact same content several times that I'm aware of.

Post quoting might end up being an issue though.

<comment><USER40> The software auto-kills duplicate posts.

You're probably seeing them because you've turned on showdead.

<comment><USER41> You're right, I did. My mistake then. Still a newb.</comment></comment></comment></comment></comment></comment>


Ask HN: How close together are your bus stops? - <AUTHOR> In London UK, distances between bus stops are on average between 100 and 200m away from each other.<p>I'm interested in finding out whether other cities in the world may have comparably short distances between bus stops and whether they have any datasets that could be used to calculate bus stop distance distributions. <comment><USER2> [https://en.wikipedia.org/wiki/General_Transit_Feed_Specifica...](https://en.wikipedia.org/wiki/General_Transit_Feed_Specification) is the most used file format. Public transport companies used to submit their information to Google Maps and similar (the 'G' used to stand for 'Google'). You can find those searching for 'GTFS <name of city>' in various open data portals.

Alternatively OpenStreetMap is a huge global dataset. Buses are a small part of [https://wiki.openstreetmap.org/wiki/Public_transport](https://wiki.openstreetmap.org/wiki/Public_transport) It's easy to extract bus stops [https://wiki.openstreetmap.org/wiki/Overpass_API](https://wiki.openstreetmap.org/wiki/Overpass_API) ([https://overpass-turbo.eu/](https://overpass-turbo.eu/)) but you're probably interested in routes as well. It's a rabbit hole of complexity, e.g. a bus terminal is multiple bus stops, some buses skip stops based on time of day, weekday, season (school buses), some stops are just for drivers to take a break or refuel, direction of route matters.

The transport view on [https://www.openstreetmap.org/#map=16/21.3308/-157.8868&laye...](https://www.openstreetmap.org/#map=16/21.3308/-157.8868&layers=T) is a pretty nice visualization. For specific questions on OSM tools there is [https://help.openstreetmap.org/](https://help.openstreetmap.org/) and a mailing list [https://lists.openstreetmap.org/listinfo/talk- transit](https://lists.openstreetmap.org/listinfo/talk-transit)

<comment><USER3> I was involved in a project where we could identify Transit deserts ([https://en.wikipedia.org/wiki/Transit_desert](https://en.wikipedia.org/wiki/Transit_desert)). Sadly the new administration cancelled this project. We were using GTFS data and US Census data to identify these. Quite interesting stuff. Perhaps the OP is interested in that as well.

</comment></comment><comment><USER4> In NYC, it depends heavily on the bus line. Some stop nearly every block (which can be as little as every 100m) whereas some have more widely-spaced stops.

The buses here are notorious for running very slowly (and thus behind schedule), and one of the proposals to speed some some slow buses is to eliminate stops on lines where they are densely clustered. It's become a subject of considerable debate, as residents and in particular older and disabled people are usually against consolidation, whereas most others accept it as a necessary cost of improving service.

The M14, which runs along 14th Street in Manhattan, is an example of where this is happening right now. Currently, the bus spends around 25% of its time standing in stations because it stops pretty much every block. There's a plan to eliminate some of its stops, but it's unclear whether it will succeed. Here's a good read on the subject: [https://nyc.streetsblog.org/2019/04/19/never-stop- stopping-r...](https://nyc.streetsblog.org/2019/04/19/never-stop-stopping- removing-bus-stops-isnt-easy-in-new-york-city-or-anywhere-else/)

<comment><USER5> I was going to mention NYC too but in terms of the Subway, which is related.

The "local" stops on a lot of Subway lines really shouldn't be there. I'm looking at you 18th Street, 28th Street, 50th Street and so on. 18th Street in particular is 4 blocks away (where 1 block = <1 minute walking) from 14th Street and the entrances to 14th Street will often extend up to 16th Street anyway (with the platform potentially right underneath).

In the other direction 23rd Street is 5 blocks away.

The Subway spends billions of dollars a year on power. Most of that power (for trains) is spent accelerating so every stop counts.

I expect the same people who are against consolidation of bus stops are against consolidation of Subway stops.

Honestly I personally have never taken a bus in NYC despite living here for nearly a decade. Distances in Manhattan are just so relatively short.

<comment><USER6> When I visited Shanghai, I noticed that late at night when there are not many passengers, they will kick everybody off the train at a random stop. They do this with a few trains in a row until there are enough people waiting in the station to fill up a train to some acceptable level.

I assume that the point of consolidating everybody into one train like this is so they can avoid wasting power decelerating/accelerating on a bunch of trains. I.e. just run all the empty ones to the terminus without stopping.

It was a bit annoying whenever it happened to us, but I think this is a better system than getting rid of heavily used local stops entirely.

Edit: As a reply explains, it's possible my description is slightly inaccurate.

<comment><USER7> Would this really save much efficiency versus the much less disruptive option of taking the trains out of commission (for the evening/morning/etc) when they get to the end of their route?

<comment><USER6> I'm really not an expert on subways, so I don't know. But I can only assume that the people who run the Shanghai metro know what they're doing.

<comment><USER7> Sorry, shouldn't have framed that as a question directed at you specifically. :)

</comment></comment></comment></comment></comment></comment><comment><USER8> _Prague_

Per [0] (2001; in Czech), average distance between subway stations is 1038m, tram stops 500m and bus stops 698m.

A related metric is walking distance from home to public transportation stop. Per [1] (2011; in Czech), most of people in the city need to walk less than 5 minutes to reach a stop. (There's a table with a breakdown by walking time and city part in chapter 7.) The same work cites average walking speed as 88.69 m/min, which gives you, for most inhabitants, <450m to reach a public transportation stop.

[0] [http://envis.praha- mesto.cz/rocenky/DZ_OO/pril_practexty/BK0...](http://envis.praha- mesto.cz/rocenky/DZ_OO/pril_practexty/BK03/2_MHD1.pdf) [1] [https://dspace.cuni.cz/bitstream/handle/20.500.11956/51223/B...](https://dspace.cuni.cz/bitstream/handle/20.500.11956/51223/BPTX_2010_1__0_262146_0_100691.pdf?sequence=1&isAllowed=y)

(EDIT: Updated units.)

<comment><USER9> _walking speed as 88.69 m /s_

cm/s ?

<comment><USER10> Czech your math. People there are blazing fast :)

</comment></comment></comment><comment><USER11> Here is an interesting article about this subject, suggesting a 400m-rule for walking distance to the next stop: [https://humantransit.org/2010/11/san- francisco-a-rational-st...](https://humantransit.org/2010/11/san-francisco-a- rational-stop-spacing-plan.html)

The city of Zurich, Switzerland recommends a tram stop every 300m-600m: [https://www.stadt- zuerich.ch/content/dam/stzh/vbz/Deutsch/Ue...](https://www.stadt- zuerich.ch/content/dam/stzh/vbz/Deutsch/Ueber%20das%20Departement/Publikationen%20und%20Broschueren/Die%20VBZ/RLV230002_SMS_SR_Planungsrichtlinie_Tram_V2.0_140301.pdf) (page 19)

</comment><comment><USER12> In Freiburg/Germany (250k inhabitants), the mean distance between bus stops is 634m, more distant than those of the tram (453m). Freiburg has more trams (72) than busses (65) running on 44 km of rails and the sum of all bus routes is 160 km. [1]

Trams run in short intervals and they are convenient when they're near, but switching from tram to bus carries a high time penalty two out of three times.

[1] [https://www.vag-freiburg.de/die-vag/ueber-uns](https://www.vag- freiburg.de/die-vag/ueber-uns)

</comment><comment><USER13> For Switzerland, that distance sounds about right, tending more towards 100m (in major cities). There is bound to be a dataset somewhere: being a tiny country means that we map everything in great detail, and the government takes these topics quite seriously. Some links to get you started:

[https://www.geo.admin.ch/en/geo-information- switzerland/geod...](https://www.geo.admin.ch/en/geo-information- switzerland/geodata-index-inspire.html)

[https://www.geo.admin.ch/en/geo-information- switzerland/geod...](https://www.geo.admin.ch/en/geo-information- switzerland/geodata-index-inspire/infrastructure-and-communication/transport- networks.html)

You can also visualize a lot of the topographic data on map.geo.admin.ch, which is surprisingly useful/flexible, if not very user friendly.

<comment><USER14> Also, your goberment ask people about stuff like if it OK to deploy 5G in the country ;-)

(I must confess I find that awesome).

</comment></comment><comment><USER15> Some discussion on this topic on this blog, e.g., [https://pedestrianobservations.com/2018/10/30/sometimes- bus-...](https://pedestrianobservations.com/2018/10/30/sometimes-bus-stop- consolidation-is-inappropriate/)

<comment><AUTHOR> thanks for the link - very interesting!

</comment></comment><comment><USER16> In Warsaw, Poland, the mean distance between bus stops is 1,041 metres. This may seem a lot, but the distribution is heavily skewed by the fact that Warsaw has 4 express bus lines: not taking these into account, the mean is 699 metres.

Source (Polish): [https://warszawa.wikia.org/wiki/Autobusy](https://warszawa.wikia.org/wiki/Autobusy)

</comment><comment><USER17> 20% of stops in Edinburgh are less than 200m from the previous stop, 40% between 200m and 300m and 20% between 300m and 400 metres.

From [http://www.edinburgh.gov.uk/download/meetings/id/58073/item_...](http://www.edinburgh.gov.uk/download/meetings/id/58073/item_72_-_public_transport_priority_action_plan)

</comment><comment><USER18> For Berlin, there is an interesting visualization of this question:

[https://verkehrsluecken.tagesspiegel.de/en/](https://verkehrsluecken.tagesspiegel.de/en/)

</comment><comment><USER19> I live in Dublin and I take the bus everyday, is mad, I'm talking sometimes less than 50m.

The stop in front of my house and the next one is only three houses away, Georgian style, so no mansions or huge houses.

The transport in Dublin is horrible and is on top 5 of most expensive public transport systems. (No subway)

<comment><USER20> If you live and work along the Luas it's not so bad. But otherwise yeah it's shite.

</comment></comment><comment><USER21> It depends on the bus!

In my local city in China, for example:

The BRT stops every 2km or so, and runs on dedicated lanes.

The tram stops every 1km or so, no variation downtown or out of town.

The 5 __buses and 6 __* buses tend to be long distance within a metropolitan area and stop every 2-500m at pickup and destination, but can run 30km only stopping a couple of times at key pick-up /drop-off locations.

Regularly numbered buses 1 though 70+ will stop every 500 meters or so, usually at each block.

There's an app, PandaBus, that shows all of the routes and stops for every stop in most Chinese cities, and has live GPS of buses for several cities. I don't know where they get the data, I'm sure you can just ask them.

In Hong Kong, numbering is a bit different and related to the city layout - basically HK is very dense in Central (Island) and Kowloon (peninsula) but due to coastal and mountainous topography very vast in the New Territories with 'new towns' being small urban pockets in the NT countryside.

Take the, IIRC, 73. The 73 route runs from Tai Po to Kowloon. The 73X does this with lots of pick-ups in Tai Po, then expressway to Kowloon with a single stop in Shatin, that's about 80km. The 73K does the same route but doesn't take the expressway and stops at every conceivable point, expending the journey time by an hour or two. HK people please correct me as it's a long time since I was in HK.

And HK also has the Toyota mini buses that have a single pickup point, drive like maniacs for 30-80km picking up speed downhill and losing momentum uphill, then drop off where you ask the driver. Good exciting ride, keep your eyes open!

</comment><comment><USER22> In Seattle we have and are currently expanding a system of "RapidRide" buses. These appear to have an average stop distance of around 0.3 miles (~500 meters)

Wikipedia claims that RapidRide routes have on average 40% fewer stops than the 'regular' line that they replaced, which would mean the 'regular' buses have stops about every 300 meters.

Anecdotally, I lived in London for a few years and now live in Seattle, and I would say these number's all roughly match my experience. Seattle's stops are spaced quite a bit further apart, but Seattle is also much less dense :)

see [https://www.theurbanist.org/2018/03/26/rainier-rapidride- met...](https://www.theurbanist.org/2018/03/26/rainier-rapidride-metro-seeks- streamlined-route-7/) and [https://en.wikipedia.org/wiki/RapidRide](https://en.wikipedia.org/wiki/RapidRide)

</comment><comment><USER23> I live in London and I wouldn't say my local bus stops are spaced at 200m intervals.

In Zone 2, sure. Not in the suburbs.

Definitely density related.

</comment><comment><USER24> Tokyo. The average distance between stops on major streets are about 200 to 400m here, except some busy areas.

[https://busmap.info/map/?q=%E6%9D%B1%E4%BA%AC%E9%83%BD%E6%96...](https://busmap.info/map/?q=%E6%9D%B1%E4%BA%AC%E9%83%BD%E6%96%B0%E5%AE%BF%E5%8C%BA)

As you can imagine, buses are just as amazing as trains in Tokyo. They're sometimes running late, but only up to a few minutes. And often they come at the exact time. (There's a time table for every bus stop.) Most buses are accessible and there are a lot of elderly people using it. (Age 70 or older can get a free pass.) When there was a once-in-a-decade snowfall last year, they delayed about 10 minutes, and that was morning rush hours. Again, they do absolutely fantastic job here.

<comment><USER25> I'm so jealous. Between your transit and your amazing baked goods.

</comment></comment><comment><USER26> In Prague the usual distance is between 400 and 600m [0].

[0] [http://standardzastavek.pid.cz/wp- content/uploads/2017/09/st...](http://standardzastavek.pid.cz/wp- content/uploads/2017/09/standard_zastavek_pid.pdf)

</comment><comment><USER27> 200m is incredibly short. I'd say the average in Bangalore is around 700metres. It varies from 500m in dense parts of the city to 1.5km in the not so dense parts.

</comment><comment><USER28> In US cities, the densest lines will have one stop per "block" — and that's frequently a regular tenth or eighth of a mile (and more regular as you move towards the newer cities in the west). So you'll typically find minimum distances of 160m or 200m and then multiples of those for express lines or less dense areas.

</comment><comment><USER29> "on average between 100 and 200m" is an imprecise statement. Where does this metric come from?

<comment><AUTHOR> I haven't got the precise details yet - I've analysed about 20 bus routes so far and they have an average distance between stops of 128.4m. But till I scale up the analysis to all bus routes, I cannot say for certain that it is the London average.

</comment></comment><comment><USER30> Stockholm: Distances vary between different line types, e.g. the backbones lines 1..4 are a different type of backbone transit offering shorter travel times by having longer distances between stops (.5-1km) and shorter invervals between buses. Regular inner city buses have shorter distances.

The free API is _fantastic_. I'd be willing to bet it's the most comprehensive public API for city public transport in the world (Happy to be proven wrong though!).

As an example This API endpoint is for stops and lines. [https://www.trafiklab.se/api/sl-hallplatser-och- linjer-2](https://www.trafiklab.se/api/sl-hallplatser-och-linjer-2)

</comment><comment><USER31> In Amsterdam, and I guess many Dutch cities, the rule is that there must be a bus or tram stop within 400m from everywhere within the built-up area, so the maximum distance between stops is about 800m. The average will be lower of course.

</comment><comment><USER32> In Chicago, there are 1,536 route miles and 10,768 stops, suggesting average spacing is about 230 meters. I'm not sure if that double counts stops that serve multiple routes but it sounds about right.

<comment><USER28> Wow, that's almost exactly what I would have guessed. The block distance in Chicago is 1/8th mile (200m).

</comment></comment><comment> a-saleh Depends on the line, heavily.

There are some, especially in the center where distances around 300m are common, in the outskirt, you could ride for a kilometer or more between stops.

I found a gis data for Prague public transport, so oyu might be able to query that: [http://www.arcgis.com/home/webmap/viewer.html?url=http://mpp...](http://www.arcgis.com/home/webmap/viewer.html?url=http://mpp.iprpraha.cz/arcgis/rest/services/DOP/Linky_MHD_dnes/MapServer)

</comment><comment><USER33> I have no statistics only anedata. In my old neighborhood in Providence RI bus stops we're within shouting distance of the next stop. This was infuriating to me and a 2 mile bus ride to downtown could take 30-40 minutes. That is literally slower than my normal walking speed (~4 miles per hour). This duration was generally due to the number of stops not traffic. Maybe I'm a fast walker, but that still seems ridiculous.

</comment><comment><USER34> Just measured the bus line I used to take from Edgewater, NJ into Manhattan (measured first stop in Edgwater to last stop in Weehawken), and it averages a little over 250m between stops, but they range from around 125m-700m between stops.

One stop that always angered me was my bus stop to the next was 125m. Basically across the intersection, and there was almost always a single person over there, causing us to accelerate then stop.

</comment><comment><USER35> Here is Buenos Aires average is around 200-300m, which I personally find too short. I remember one time seeing two bus stops literally 20-25 meters away from each other. The bus needed to take left on a two lane road so it would circle the block, there was a bus stop just before entering the circle and just before leaving it. Driving distance was ~400m, but walking was a few steps.

</comment><comment><USER36> I guess one could use openstreetmap data here, since they have pretty comprehensive coverage of bus stops, at least in Europe.

<comment><USER37> Also, national or regional data might be more complete.

If you can speak enough German to navigate the download, you can e.g. find geodata of all bus stops in Zurich at [https://maps.zh.ch/?topic=ZVVZH&showtab=ogddownload](https://maps.zh.ch/?topic=ZVVZH&showtab=ogddownload) (they will only deliver to email addresses, so I cannot link the actual data here).

<comment><USER38> Zürich Tram and Bus distance (beeline) between stops of trips:

Mean 199m

Median 172m

Min 14m (Zürich, Central <-> Zürich, Central Polybahn)

Max 678m (Pfäffikon SZ, Bahnhof <-> Pfäffikon SZ, Schiffstation)

According to a dataset of 1744 trips from [https://data.stadt- zuerich.ch/dataset/vbz_fahrplandaten_gtfs](https://data.stadt- zuerich.ch/dataset/vbz_fahrplandaten_gtfs)

<comment><USER37> Really cool, and thanks for finding a much more accessible data set than I managed to!

For people non-familiar with Switzerland, though, it needs pointing out that Pfäffikon SZ is no longer in Zurich city nor Zurich state, but Schwyz (thus the SZ). It still comes up in that data set since it is served by ZVV, the Zurich transport authority. It would also be great to know how you group stops together as "the same stop, just different parts of it". I.e. Central vs. Central Polybahn - I would say these are actually colocated, just served by different lines (tram vs. furnicular).

</comment></comment></comment></comment><comment><USER39> I believe that while there are various guidelines and studies, it is typically up to the transit agency itself to determine stop density and locations.

There are many companies that provide transit planning solutions which use GIS (with census data) to aid the process.

</comment><comment><USER40> As others have said varies greatly, but it seems most common around here (Beaverton / Hillsboro, Oregon) that they like to stop every block, sometimes on opposite sides on an intersection - which honestly baffles my mind but whatever.

</comment><comment><USER41> In China, big cities will set a distance of 500 meters between two bus stops. In my hometown which is a quite small city with 500k population, bus stops doesn't really work and every time you want to get on, just wave your hand. lol

</comment><comment><USER42> In Houston, the bus and rails lines have stops about every 200m (2 blocks). Many of the lines have big gaps between stops (in the multiples of KMs), typically going to a transit center.

</comment><comment><USER43> In Washington, DC, the distance varies considerably, but 200m sounds about right for the average. WMATA does have a "next bus" service that I see people using.

<comment><USER44> Notably there are also several "MetroExtra" buses that run similar routes as popular bus lines but make about 1/3 as many stops and are therefore much faster.

The NextBus service DC uses is clearly using a very naive algorithm that is often (consistently) too fast or slow. Some of the better apps modify it or add their own data.

<comment><USER43> Yes, WMATA has managed to move a lot of S9 buses up and down 16th St. NW at busy times of day. Judging from what I see, the S9 is efficient at moving such people as get on, less so in moving numbers of people. It is routine to see three mostly empty S9s go by a stop before a local bus (S1/S2/S4) arrives.

</comment></comment></comment><comment><USER45> In Vienna, Austria stops are (AFAIK) very rarely less than ~300m away from each other, granted I'm horrible at guessing distances so perhaps I'm way off.

</comment><comment><USER46> In Indonesia, the city buses stop wherever it likes. In Jakarta though, the city managed bus (TransJakarta) have dedicated bus stop at about ~1km.

</comment><comment><USER47> It's obviously density related, even in London.

<comment><USER48> It is also obvious that nobody on HN lives in the sticks. Or, if they do, then they drive and therefore have precisely zero interest in bus stops.

My country dwelling parents have a bus stop outside their door. There is one bus per day - weekdays only - and that is only in one direction. This I find mind-boggling. A shopping trip would require an overnight stay in town and for a full circuit of the route to be completed. Somewhere there is a bus driver getting paid for that and a local authority that has mandated this service be put on.

<comment><USER49> That does seem extreme. That said, a lot of small town and semi-rural public transit seems to operate at a level where it's marginally better than nothing but not much better for those who have alternatives.

Around the exurbs/adjacent small city where I live, there is a small bus service that connects the Walmart, commuter rail, city center, etc. But I'd be pretty sure it's mostly used by those who can't drive.

</comment></comment></comment><comment><USER50> I feel sad about my country (Philppines) as buses and jeepneys could literally stop anywhere they like which results into heavy traffic.

</comment><comment><USER51> In São Paulo It is usually between 200m and 600m, ideally 400m.

But it is very irregular. There are lines with up to 1km between stops

</comment><comment><USER52> London also has bus route 389 - the entire route is I think 1.5 miles, with something like a dozen stops

<comment><USER53> My rough calculations give it 15 stops for 2420m in direction 1 (avg 160m), and 2235m in direction 2 (avg 148m).

Alas, it appears that route 631 has it beat - 1440m in direction 1 (avg 130m), 1751m in direction 2 (avg 134m)

(although, peculiarly, the information in TfL's bus route download doesn't match what you get from the web site when you look up 631.)

<comment><AUTHOR> Using TfL open API

\</comment></comment></comment><comment></comment><comment></comment><comment></comment><comment>-----

389 inbound:

min: 24.14811016418819

lq: 63.13737031546762

med: 117.45915732519208

avg: 159.1719773263877

uq: 188.0955557392336

max: 845.60445291754

389 outbound:

min: 27.01945592261999

lq: 41.34298814984834

med: 117.00503319935248

avg: 146.97253048021068

uq: 167.28703169991314

max: 809.8962084249061

631 inbound:

min: 7.0860750640801

lq: 27.685480182275676

med: 104.91095883281287

avg: 128.12981380619047

uq: 218.11267557818746

max: 363.41330216008436

631 outbound:

min: 7.636546343123111

lq: 45.34651661429212

med: 105.97332735159804

avg: 135.50969372368004

uq: 203.01187569586028

max: 363.41330216008436

<comment><USER53> Yeah, I got my numbers from `bus-sequences.csv` downloaded from the API site.

</comment></comment><comment><USER54> Here's an interesting write-up about Seattle. The tldr is that it's about 280 meters for the median, 341 for the mean, in the city proper.

[https://www.quora.com/What-is-the-average-distance- between-s...](https://www.quora.com/What-is-the-average-distance-between- stops-for-Metro-buses-in-Seattle)

<comment><USER55> Feels roughly right. My only other observation on seattle buses is that some of the more ridiculous routes have stops every two blocks on an Ave (north- south), which works out to one every 200m or so, if you use the rule of thumb that the most uniform parts of the city have 16 blocks per mile.

</comment></comment><comment><USER56> in the East Dallas Texas neighborhoods on major roads i would guess a little under a 1/4 mile. Probably a 5-10 min walk between them.

</comment><comment><USER57> İzmir: 300m in city proper, 100m in suburbs.

<comment><USER58> Stops in the suburbs are _closer_ than in the city center?

<comment><USER57> Yes, because smaller buses run in suburbs. This does not include highway strips, which retain 300m stop spacing in suburbs, too. Example route: [https://www.eshot.gov.tr/tr/UlasimSaatleri/501/288](https://www.eshot.gov.tr/tr/UlasimSaatleri/501/288) Disclaimer: I live very close to this bus route</comment></comment></comment>


Ask HN: What is your example of 'theory-induced blindness'? - <AUTHOR> What examples have you come across where a person or group was unable to accept flaws in a theory because they have already built the theory into their mental model of the world?<p>For example, some economists do not accept evidence of the 'low-volatility anomaly' because of their belief in the efficient market hypothesis. <comment><USER2> Every theory in every field has this, from theology to physics.

At the theology end of the spectrum, theories can be incredibly flawed (in the sense of being terrible predictors of experimental outcomes) and still attract new believers.

At the physics end of the spectrum, while the best theories are slightly flawed, they work well enough that rational people choose to build a worldview around them rather than throw up their hands in despair.

The low-volatility anomaly is more like the physics end of the spectrum. Empirical data doesn't quite match the theory, but nobody has a definitively better theory. Economics is the study of rational actors, but some actors are irrational, so results will never match the real world exactly.

(The low-volatility anomaly is partly a principal-agent problem: the principal has a rational risk/return tradeoff, but brokers rack up more fees with high- risk hedging strategies.)

Like when I asked my first-grader what's 4+5 and she said "6?", that doesn't shake my belief in the theory of arithmetic.

<comment><USER3> I wonder if the low-volatility anomaly is connected with this one:

In theory people should get paid for accepting risk in their personal careers. Gig economy jobs should pay more for the benefits you don't get. Government employees used to get paid less for more security. By that measure adjuncts should get paid more than tenured faculty members.

Practically it is the other way around. One take could be that pay and security both correlate to power. Another one is that security is good for your health, career development, networking, etc. Another one is that the idea that "risk and reward are correlated" aren't true, and that risk is really like what most people (not hedgies) think risk is... A bad thing.

<comment><AUTHOR> My understanding of this particular anomaly is:

1\. The majority of market money is handled by institutional funds, which also have leverage constraints

2\. Institutional funds are generally measured by their ability to beat a market benchmark, like the S&P500, on a short term (quarterly or annual) basis

3\. To beat the market, fund managers must invest in stocks that diverge from the market. This means high beta stocks - aka stocks with higher systemic risk (by definition, if beta=1.0 it will match - but not outperform - the market)

4\. Most fund managers display an overconfidence bias. In other words, they think they can pick the winners of the high-beta stocks. While they may be able to do so in a particular year, rarely do the same funds pick winners consistently over a long stretch of time.

So the low-volatility anomaly is the convergence of incentives (you are measured by your ability to beat the market) and the overconfidence bias of behavioral economics (you think you can pick the winners of the high-beta stocks). As large amounts of institutional funds are funneled to high-beta stocks, it leaves low-beta stocks relatively undervalued

</comment></comment></comment><comment><USER3> I want to say economics in general. Some specific cases:

* the idea that small increases in the minimum wage will lead to unemployment

* lack of ability to reckon with "secular stagnation"

* Rise of China despite China being the only place that tells neoliberals to screw off (e.g. try having a protest for neoliberalism and they'll harvest your organs)</comment>


Mako: a stack-based VM game console in F# - <AUTHOR> https://github.com/JohnEarnest/Mako

<comment><USER2> This isn't in F#</comment>


Co-Founder for Smart Watch Startup - <AUTHOR>

Looking for a Technical Co-founder for Smart Watch startup. Looking for someone with hardware, systems, Programming (Android OS/App) development experience. We are in Bay CA, bootstrapped right now <comment><USER2> Well, I have most of those skills but alas I'm deep in my own hardware/software startup at the moment. (See profile)

I'm sure you are already making the rounds at the hardware related meetups in the Bay Area but beyond that I think you might get more responses if you posted what you and your existing team bring to the table beyond just "I've got this smart watch startup I need another Co-Founder for." Even if you are non-technical your role is obviously hugely important and so you need to sell yourself and your team. Also, I'd recommend you post your email address in your profiles about section so people can contact you privately. Cheers.

</comment><comment><USER3> What do you bring to the table?</comment>