# Tag Info

64

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

52

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

46

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

19

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

18

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

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

12

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

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.

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

8

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

8

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

7

I seem to recall that early versions of the shell didn't have a comment syntax. A line starting with : (which probably would have been an actual executable, similar to /bin/true) would have been the best alternative. Here's a man page for the ancient Thompson shell (no relation); there's no mention of any comment syntax.

7

( return 1 ) This runs in a subshell. It does terminate the subshell immediately, and if you caught that shell's return code, it would be 1. The function itself returns 0 on the line after that. (See Grouping Commands in the Shell Command Language specification.) Compare with the {} form that doesn't introduce a subshell: #! /bin/sh func () { ( ...

7

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.

7

Bash has a (builtin) command builtin, which does exactly what you need. Replacing cd with builtin cd in your function will fix the recursion.

6

You probably have the man page for echo because most systems have an echo binary in /bin, even though most shells provide a built-in anyway; you're seeing the man page for that binary. The man pages for all the other commands you're missing are in the POSIX Programmer's Manual (man section 1P). How to install it will depend on your distro; on Gentoo they're ...

6

declare is a builtin function and it's not available with /bin/sh, only with bash or zsh (and maybe other shells). The syntax may differ from one shell to another. You must choose your sheebang (#!) accordingly.

6

It's possible with zsh: $CONS=( b c d )$ VOWEL=( a e i o u ) $echo$^CONS$^VOWEL ba be bi bo bu ca ce ci co cu da de di do du Or es: ; VOWEL=( a e i o u ) ; CONS=( b c d ) ; echo$VOWEL^$CONS ab ac ad eb ec ed ib ic id ob oc od ub uc ud With bash or ksh93, you'd have to do something convoluted like: VOWEL=( a e i o u ) CONS=( b c d ) ... 5 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, ... 5 Writing a shell script in a specific shell means having that shell installed. The only standard is to have csh and sh installed over all Unix variants. So, if you wanted your script to run on Solaris, *BSD, and GNU then you would have to write it in, say, the Bourne shell. However, most Unix commands have different syntaxes under different ... 5 Bash built-ins are inconsistent and poorly documented. Here's an example:$ help command command: command [-pVv] command [arg ...] Runs COMMAND with ARGS ignoring shell functions. If you have a shell function called 'ls', and you wish to call the command `ls', you can say "command ls". If the -p option is given, a default value is used ...

5

declare is a bash and zsh extension. On your system, /bin/sh is neither bash nor zsh (it's probably ash), so declare isn't available. You can use typeset instead of declare; they're synonyms, but typeset also works in ksh. In ash, there's no equivalent to typeset -i or most other uses of the typeset built-in. You don't actually need typeset -i to declare an ...

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