Tag Info

66

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 ...

59

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 ...

55

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 ...

54

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 ... 28 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

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 ...

23

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², ...

21

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 ...

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 ...

18

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 ...

16

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} 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 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 ... 15 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 ... 13 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 ... 13 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. ...

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

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). ...

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.

9

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. 9 There is a shortcut in bash to sidestep keywords, without having to specify a path or use another builtin like command: Escape it with a backslash. =^_^= izkata@Izein:~$ time real 0m0.000s user 0m0.000s sys 0m0.000s =^_^= izkata@Izein:~\$ \time Usage: time [-apvV] [-f format] [-o file] [--append] [--verbose] [--portability] ...

9

While waiting for one of the heavyweights to come and give a full historical perspective, I'll give you my more limited understanding. Built-in commands like alias, cd, echo etc are part of your shell (bash, zsh, ksh or whatever). They get loaded at the same time the shell is and are simply internal functions of that shell.

9

Let's say if I type in cd in my shell. Is cd loaded from the memory at that moment? My intuition is that these built-in commands are pre-loaded to the system memory after the kernel has been loaded, but someone insisted that they are loaded only when I actually invoke the command... In broad terms the other answers are correct -- the built-ins are ...

8

A builtin is a command provided by the shell, rather than by an external program. Here are the lists for bash's builtins (they are also listed in the bash man page) and zsh's builtins. ksh provides a list by running builtin. To know if a particular command is a builtin, you can run type command. Try type for and type ls to see this.

8

The : built-in was already in the Thompson shell — it's documented for Unix V6 in 1975. In the Thompson shell, : indicated a label for the goto command. If you never attempted to call goto on a line beginning with : , that line was effectively a comment. The Bourne shell, the ancestor of Bourne/POSIX shells as we know them, never had a goto that I know of, ...

8

zsh is one of the few shells (the other ones being tcsh (which originated as a csh script for csh users, which also had its limitation, tcsh made it a builtin as an improvement)) where which does something sensible since it's a shell builtin, but somehow you or your OS (via some rc file) broke it by replacing it with a call to the system which command which ...

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