Hacker News new | past | comments | ask | show | jobs | submit login

You probably have the `printf` in your PATH. However, if you type `printf` on a bash script, a builtin will be used instead.

Try a small benchmark to see the results of /usr/bin/printf vs printf. It really makes a difference (not invoking an external program is a huge performance win).

The author is indeed confused though. `test` for example, is also a builtin. You can have an empty PATH= and still invoke printf, test, echo and some few others.

The list is weird.




Type `help` in your shell to see a list of all the builtins.


In _some_ shells! (most user shells anyway). `dash` for example does not have help.

Some form of builtin list is always on the man pages though.

There's no good way of telling if a builtin exists programatically (for, let's say, feature detection).

There's an almost good way with `{ PATH=; command -v isthisreallife; }` and some shells will provide a `builtin isthisreallife` that you can use without having to nuke the PATH variable.


I appreciate pedantry as much as the next person, but I think it's safe to say that if you're using a shell without support for `help` you can make your way without it.

As a more practical suggestion, I find functionality detection is much less important since I learned to disavow all knowledge of a script when sharing it


> There's no good way of telling if a builtin exists programatically (for, let's say, feature detection).

Doesn’t the `type` command (technically a builtin) meet your requirements?


It kinda does, and it is portable enough (modern bash zsh ksh dash busybox), thanks!

Of the mainstream packaged shells, it fails only on `posh`, but that's fine, posh is super austere, it also lacks `command`.

However, I will probably still use `command -v` for sporadic uses. That's because I don't need a subshell to capture the output:

    OLDPATH=$PATH;PATH=
    if command -v echo
    then echo is builtin
    fi
    PATH=$OLDPATH

    if test "$(type echo)" = "echo is a shell builtin"
    then echo is a builtin
    fi
`type` however seems to be able to pick up more stuff, so I might use it some cases like this:

    case $(type echo) in
        'echo is a shell builtin') do_something;;
        'echo is aliased'*) do_something_else;;
        'echo is /'*) do_something_else_entirely;;
    esac
It kinda fits an early feature detection that I could put in a more sensible place (my lib init) and pay the subshell cost only once.




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

Search: