views:

6550

answers:

5

I would like to know exactly how the "Is" command works in Linux and Unix.

As far as I know, ls forks & exec to the linux/unix shell and then gets the output (of the current file tree. eg./home/ankit/). I need a more detailed explanation, as I am not sure about what happens after calling fork.

Could any one please explain the functionality of the 'ls' command in detail?

+21  A: 

ls doesn't fork. The shell forks and execs in order to run any command that isn't built in, and one of the commands it can run is ls.

ls uses opendir() and readdir() to step through all the files in the directory. If it needs more information about one of them it calls stat().

Mark Baker
As a point of interest, I think you'll find it stat()'s just about every file in the directory, especially if colors and/or file type pre/suffixs are turned on.
Matthew Scharley
On a different note, why does the shell need to fork for foreground processes?
Matthew Scharley
monoxide: an exec() without a fork() will replace the currently running process, which means your shell would vanish the first time you ran a command.
Greg Hewgill
Thanks Mark, here is the decelaration part from K Dirent *readdir(DIR *dfd); void closedir(DIR *dfd);
Ankit S
if ls is a built-in, like in some standalone shells, does it still fork and exec?
warren
If it is built-in, it does not need to start another program, so an exec() is not required. Whether it fork()s or not depends on the shell and the situation -- for example, if `cat` was built-in, it would still be easier to fork to handle something like `cat | cat`, but forked `read` is hard.
ephemient
@Mark: it also uses lstat() since otherwise it only sees the permissions of the file at the far end of a symlink and not the symlink itself.
Jonathan Leffler
@monoxide: the shell can run other programs in exactly one of two ways - by using exec() to replace itself with the other program, or by using fork() and then exec(). Those are the only mechanisms available in Unix (unless you count pthread_spawn()).
Jonathan Leffler
jonathan, the pthread library is based on the clone() system call (in linux - other unix versions with kernel threading will have something similar but probably not identical). Using clone() directly and then exec() is another way you could launch a program, though not one that's useful in practice.
Mark Baker
+8  A: 

To add to the answer, in The C Programming Language book (K&RC) they have given a small example on how to go about implementing ls. They have explained the datastructures and functions used very well.

Sushant
+3  A: 

To understand what ls does, you could take a gander at the OpenSolaris source: http://cvs.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/cmd/ls/ls.c.

If that´s overwhelming, on Solaris you start by using truss to look at the system calls that ls makes to understand what it does. Using truss, try:

truss -afl -o ls.out /bin/ls

then look at the output in ls.out

I believe that trace is the equivalent to truss in Linux.

tpgould
The Linux version of "truss" is called "strace".
Thomas
+3  A: 

If you really want to understand the detailed innards of ls, look at the source code. You can follow tpgould's link to the Solaris source, or it's easy to find the source online from any Linux or BSD distribution.

I'll particularly recommend the 4.4BSD source.

As I recall, ls starts by parsing its many options, then starts with the files or directories listed on the command line (default is "."). Subdirectories are handled by recursion into the directory list routine. There's no fork() or exec() that I recall.

mpez0
A: 

more information about unix ls command

ls command options with practical examples