Hot answers tagged

143

The cd command modifies the "current working directory", right? "current working directory" is a property that is unique to each process. So, if cd was a program it would work like this: cd foo the cd process starts the cd process changes the directory for the cd process the cd process exits your shell still has the same state, including current working ...


74

cd in addition to being a shell builtin, is actually also a program on POSIX compliant OSes. They must provide independent executables for regular utilities, like cd. This is for example the case with Solaris, AIX, HP-UX and OS X. Obviously, a builtin cd is still mandatory as its external implementation doesn't change the current shell directory. However, ...


70

The difference between [ and [[ is quite fundamental. [ is a command. Its arguments are processed just the way any other commands arguments are processed. For example, consider: [ -z $name ] The shell will expand $name and perform both word splitting and filename generation on the result, just as it would for any other command. As an example, the ...


61

From your comments, you seem to be confused about exactly what a shell is. The kernel is responsible for managing the system. It's the part that actually loads and runs programs, accesses files, allocates memory, etc. But the kernel has no user interface; you can only communicate with it by using another program as an intermediary. A shell is a program ...


60

In V7 Unix — where the Bourne shell made its debut — [ was called test, and it existed only as /bin/test. So, code you would write today as: if [ "$foo" = "bar" ] ; then ... you would have written instead as if test "$foo" = "bar" ; then ... This second notation still exists, and I find that it's more clear about what's going on: you are calling a ...


59

type tells you what the shell would use. For example: $ type echo echo is a shell builtin $ type /bin/echo /bin/echo is /bin/echo That means that if, at the bash prompt, you type echo, you will get the built-in. If you specify the path, as in /bin/echo, you will get the external command. which, by contrast is an external program that has no special ...


58

There are two classes of builtins: Some commands have to be built into the shell program itself because they cannot work if they are external. cd is one such since if it were external, it could only change its own directory; it couldn't affect the current working directory of the shell. (See also: Why is cd not a program?) The other class of commands are ...


44

cat is hashed (/bin/cat) is just like cat is /bin/cat (that is, it's an external program). The difference is that you already ran cat in this session, so bash has already looked it up in $PATH and stored the resulting location in a hash table so it doesn't have to look it up again in this session. To see all the commands that have been hashed in your ...


40

From the Bash introduction (What is a shell?): Shells also provide a small set of built-in commands (builtins) implementing functionality impossible or inconvenient to obtain via separate utilities. For example, cd, break, continue, and exec) cannot be implemented outside of the shell because they directly manipulate the shell itself. The history,...


31

help read help read | less In zsh: run-help read or type read something and press M-h (i.e. Alt+h or ESC h). If you want to have a single man command so as not to need to know whether the command is a built-in, define this function in your ~/.bashrc: man () { case "$(type -t "$1"):$1" in builtin:*) help "$1" | "${PAGER:-less}";; # built-in ...


24

There are three levels of built-in utilities: Some utilities are really part of the shell as a programming language, even though they are not reserved words. They are control flow utilities (., :, break, continue, return, trap, exit, exec, eval), parameter-related utilities (set, unset, shift, export, readonly, local¹, typeset¹), alias utilities (alias², ...


24

Instead of using which, which doesn't work when you need it most, use type to determine what will run when you type a command: $ which set ./set $ type set set is a shell builtin The shell always looks for builtins before searching the $PATH, so setting $PATH doesn't help here. It would be best to rename your executable to something else, but if your ...


22

In ksh, bash and zsh, time is not a command (builtin or not), it's a reserved word in the language like for or while. It's used to time a pipeline1. In: time for i in 1 2; do cmd1 "$i"; done | cmd2 > redir You have special syntax that tells the shell to run that pipe line: for i in 1 2; do cmd1 "$i"; done | cmd2 > redir And report timing ...


21

For April Fool's this year, I wrote a standalone version of cd. No one got the joke. Sigh. Anyone who isn't sure that cd must be built into the shell should download it, build it, and try it. Read its man page, too. :)


20

A shell script is an executable program. That's why type says that it is one. A shell script is as much an executable command as a perl script, a python script, a native ELF executable, a cross-architecture executable being executed by Qemu through Linux's binfmt_misc mechanism, etc. Any executable file is an executable command, it doesn't matter what ...


19

You can use the command shell built-in to bypass the normal lookup process and run the given command as an external command regardless of any other possibilities (shell built-ins, aliases, etc.). This is often done in scripts which need to be portable across systems, although probably more commonly using the shorthand \ (as in \rm rather than command rm or ...


18

The : builtin is also useful with the Bash "assign default values" shell expansion, where the expansion is often used solely for the side effect and the value expanded is thrown away: # assign FOO=bar iff FOO is unset : ${FOO:=bar}


17

There is a third reason for some commands to be built-in: They can be used when running external commands is impossible. Sometimes a system becomes so broken that the ls command does not work. In some cases, an echo * will still work. Another (more important!) example is kill: If a system runs out of free PIDs, it is not possible to run /bin/kill (because ...


17

It appears the :s in your script are being used in lieu of true. If grep doesn't find a match in the file, it will return a nonzero exit code; as jw013 mentions in a comment, if errexit is set, probably by -e on the shebang line, the script would exit if any of the greps fail to find a match. Clearly, that's not what the author wanted, so (s)he added || : to ...


16

Assuming env is in your path: env kill -p http env runs the executable file named by its first argument in a (possibly) modified environment; as such, it does not know about or work with shell built-in commands. This produces some shell job control cruft, but doesn't rely on an external command: exec kill -p bash & exec requires an executable to ...


15

I can think of two places I've used : in the past. while : do shell commands some exit condition done That is a forever-loop. function doSomethingStub { : } Put in a stub function, just to get top level flow of control correct. One use I've seen back in the Old Days: Instead of a #!/bin/sh (or whatever) line, you'd see a : line. Some of ...


14

Highest priority is bash alias, then special builtins (only in POSIX mode), then functions, then builtins, then a search in $PATH. To execute a builtin, use builtin test. To execute an external application, use an explicit path: /bin/test. To ignore functions and aliases, use command test. To bypass just alias, use \test or any other kind of expansion. It'...


14

exec is often used in shell scripts which mainly act as wrappers for starting other binaries. For example: #!/bin/sh if stuff; EXTRA_OPTIONS="-x -y -z" else EXTRA_OPTIONS="-a foo" fi exec /usr/local/bin/the.real.binary $EXTRA_OPTIONS "$@" so that after the wrapper is finished running, the "real" binary takes over and there is no longer any trace ...


13

I can't imagine any reason to write this code, and I'm not quite sure what the person who wrote this code was trying to achieve. wait here does nothing -- from its perspective, there are no child processes, so it will just exit immediately and basically act as a noop (wait itself executes in a child process due to command substitution, but that's unrelated). ...


12

Greg's Wiki has a post on adapting bash scripts for Dash that points out a lot of 'bashisms' - extra features that are non-standard but are a part of bash. Avoiding those bashisms can help to make your script friendlier to different environments. This particularly answers some of your questions. For instance, yes, there are operators that differ (like ==), ...


12

Try this: bashman () { man bash | less -p "^ $1 "; } You may have to hit n a couple of times to get to the actual command instead of a paragraph that happens to have the command name as the first word.


11

According to the Bash Reference Manual, it's about convenience. Shells also provide a small set of built-in commands (builtins) implementing functionality impossible or inconvenient to obtain via separate utilities. For example, cd, break, continue, and exec) cannot be implemented outside of the shell because they directly manipulate the shell itself. ...


11

set is a builtin in bash (and probably most other shells). This means that bash will not even search the path when looking for the function. As a side remark, I would strongly advice against adding . to the path for security reasons. Imagine for example cding out of /tmp after any other user added an executable file /tmp/cd.


10

Options for compgen command are the same as complete, except -p and -r. From compgen man page: compgen compgen [option] [word] Generate possible completion matches for word according to the options, which may be any option accepted by the complete builtin with the exception of -p and -r, and write the matches to the standard output For options [...


10

set isn't just a builtin, it is a POSIX special builtin. There are a few builtin commands which are standards-specified to be found in a command search before anything else - $PATH is not searched, function names are not searched, and etc. Most builtins which are not special are actually required by the POSIX standard to be found in your $PATH before the ...



Only top voted, non community-wiki answers of a minimum length are eligible