UNIX file system/directory structure

naming rules and directory commands

default directory

When you first log in to the UNIX system, you are usually placed in your home directory.    The directory you are in at that time is called the current directory.  So at the time right after you first log into the system, the current directory is your home directory, but which directory is current can be changed by you easily, but which directory is your home is controlled by the system administrator.

When naming a file as the argument for a command, the location of the file will be assumed to be the current directory unless it is otherwise stated in that command line.  For example

% more this.file

is the command to display the contents of the file named as the argument to the screen one screenful at a time.  The argument is shown in italics to show that you replace that argument with the name of any file.  When the name is given in this way, the file here shown as this.file, would be a child of the current working directory.  If you specify the location of the file, it appears before the actual name, as shown when the directory structure was described.

There are many ways to indicate the name of the directory.    One obvious distinction is between the references which are absolute in contrast to the references which are relative.  The notation includes:

Looking at the beginning of the complete filename…

It means …

Example…

If there is a / (slash) at the beginning,

Start at the root directory (the other slashes after the beginning are delimiters)

/this/that/my.file

go to the root, and then to the root's child named this, and then to the child of this named that and then to the child of that named my.file

If there is a . (period) at the beginning,

Start at the current working directory

./that/my.file

go to the current directory, and then to the current directory's child named that and then to the child of that named my.file

If there is a .. (period, period) at the beginning,

Start at the directory which is the parent of the current directory

../this/that/my.file

go to the parent of the current directory, and then to the parent's child named this, and then to the child of this named that and then to the child of that named my.file

If there is a ~ (tilde) at the beginning with no name following it,

Start at your own home directory

~/this/that/my.file

go to the home of the user who typed this name, and then that home's  child named this, and then to the child of this named that and then to the child of that named my.file

If there is a ~ (tilde) at the beginning with a name following it,

Start at the home of the user ID given by the name indicated

~jplane/this/that/my.file

go to the home of the user jplane this name, and then that home's  child named this, and then to the child of this named that and then to the child of that named my.file

If there is nothing indicating the directory (notice no /, ., .., or ~ at the beginning)

Start at the current working directory

this/that/my.file

go to the current directory, and then to the current directory's child named this, and then to the child of this named that, and then to the child of that named my.file

 

 

These notations can also be mixed in other ways such as

~jplane/../this/my.file

which  would mean go to the home of the user whose login id is jplane, then to that home's parent, then to that parent's child named this (which would actually be a sibling to the home of jplane) and then to the child of this named my.file.

It is easy to look at these names similar to a name of a person.  If you are familiar with a person who is in the current room (so that there would be no ambiguity), you may just refer to that person by his/her first name.  For example: "Mike is leaving now."  This would only be possible if you were referring to the one and only Mike currently in the room (or for connection to UNIX - in the current working directory).  If there was more than one Mike to whom you could be referring you may need to give more information about to which Mike you are referring.  We do often do this with people by using a last name, but that could also be ambiguous since there could be two people with both the same first and last names.  Since names have to be unique within a location (directory),  we can instead refer to that person by where he lives.  "Mike, who lives in Butare, is leaving now" and "Mike, who lives in College Park, is leaving now" would refer to two different Mikes based on where they live.

 

Notice that the name of a directory can be followed by a slash delimiter.  The name of a file is always only at the end (and can't be followed by a slash).  This shows that directories can have children while files can not.  It also shows that a child can be either a file or a directory (often referred to as a "subdirectory" since it is a portion of the parent directory).  The name of a directory or a file must be unique - a parent can not have two children which both have the same name.

The characters of the file/directory name are case sensitive (upper and lower case are distinct).  The characters used in a filename are usually the uppercase letters ('A' - 'Z'), lowercase letters ('a' - 'z'), the numeric characters ('0' - '9'), and the period ('.').  All other characters except the forward slash ('/') are allowed, but we often restrict to only these because several of the other characters have meta-meanings (described further a little later on).  A meta-meaning indicates that it has a meaning to the shell which is beyond just being that character. 

The period is one example of a meta-character when it appears as the first character of the actual file/directory name.  I use the term actual name to indicate this name does not include a location.  A file or directory named .that.one is completely legal (notice the period which appears as the first character) and it completely distinct from a file/directory named that.one (which has no period at the beginning).    The period as the first character of the file/directory name indicates that the file should be considered "hidden".  A hidden file/directory is just like a non-hidden file except that when you request a listing of the current directory by using the ls command, the shell will assume you do not want to see the "hidden" children.  The files/directories that are hidden are often used for setup or automatic files that the user should not need to see or change on a regular basis.    In order to see the hidden children listed along with the non-hidden, you would need to add the -a option to the ls command (-a stands for "all").

When you give the ls command without any options or arguments, the non-hidden children of the current working directory are listed.  Since they are all children, there is no distinction made by the shell to tell which are files and which are directories.    In order to have the shell indicate which of the children are files and which are directories, you would use the -F option with the ls command.  The -F option will cause the names of the children which are directories to be marked by a slash after the name in the listing.   The regular files will have no markings after the name.  If the file is an executable file, it will be marked by a asterisk (*) after the name.  There is one other marking that will be introduced later.

     When you give the ls command with an argument,  that argument is usually used to indicate the directory for which you would like to see the listing.  You would need to give this argument if you would like to see the listing of any directory other than the current working directory.  For example, if you give the command       ls /this/that   (where that names a directory) you would be requesting to see the listing of the directory that which is a child of this which is a child of the root directory.  That directories children would then be listed.  The ls command though also allows you to give an argument which is the name of a file rather than the name of a directory.  For example, if you give the command ls that.file   (where that.file names a file) it will list the file named that.file if it exists as a child of the current working directory, and it will list nothing if there is no file named that.file in the current working directory.  Notice, it will not list the contents of the file, its purpose is to list the contents of a directory.   The more command would be used to list the contents of a file, but can not be used to list the contents of a directory.

other commands for the directory structure

 cd = change directory  

The cd command is used to move to a different directory - in other words to change which directory is the current working directory (or default directory).  The cd command is usually used with a single argument which names the destination directory (the type of the argument (if specified) must be the name of a directory which already exists.  If you give no argument, the default value is your own home directory.  If you give an argument which is not the name of a directory that exists, you will receive an error message and no change in directory will take place.   For examples click here.

pwd = print working directory  

The pwd command is used to have the shell tell you which directory is current.  It will display the full name of that directory.  The full name includes the ancestry from the root directory all of the way to the name of the actual current directory.  Since the names of children are unique to a directory, this path from the root gives a unique identity for the directory being named.

more =  display the contents of a file   For  examples click here.

The more command is used to display the contents of a file to the screen.  It will display the file one screenful at a time giving you the chance to read it before it scrolls off the screen.  It will interpret the file according to the rules of ASCII, so if the file was intended to be interpreted that way it will display the characters in a readable format.  If the file was not intended to be interpreted according to the rules of ASCII, those rules will be used to interpret the file anyway and you will most likely see a lot of garbage characters that and will not be able to read the contents of that file.  When you give the command to more a file, the first page of the file will be displayed, a prompt will appear in the bottom left corner to let you know you are using more to display the file, and you will be placed into a different environment which has its own set of commands.  A closely related command is the less command.  It has approximately the same purpose, but was designed later and so has some additional features.  Many UNIX systems have both of these available.  For examples click here.

rm =  remove (delete)

The rm command is used to delete a file from the directory structure.  The argument to this command should specify the name of the file you want to remove (either using a relative or an absolute method of reference).  The file named will be removed.  This is a permanent removal and should be done with care because once a file is removed it is gone and its current version can not be recovered (unlike Windows or Macintosh which move a deleted file to the trash can or recycling bin from where it can be recovered). For examples click here.

cp =  copy (duplicate)

The cp command is used to duplicate the contents of a file.  The cp command requires 2 arguments: the first one tells what is being copied (the source) and the second tells to where it is being copied (the destination).  If the second argument is the name of a file that already exists, the old file will have its contents replaced by the contents named as the source in the copy.  If the second argument is the name of a file that does not already exist, the file will be created.  If the second argument is the name directory that already exists, the file's name is assumed to be the same as the name of the source file and the effects of replacing or creating the file takes place the same as if the file name was specified.  For examples click here.

mv =  move (change location)

The mv command is used to move the contents of a file.  The mv command requires 2 arguments: the first one tells what is being moved (the source) and the second tells to where it is being moved (the destination).  The rule for replacing or creating files is the same as described above for the cp command.  For examples click here.

mkdir =  make directory

The mkdir command is used to create a new, empty directory.  The argument given to this command must be the name of the directory you would like to create.  Remember that names within any directory must be unique so do not use a name that already exists.  You can give the name using any absolute or relative naming method shown earlier.  For examples  click here.

rmdir =  remove directory

The rmdir command is used to remove an already empty directory.  The argument given to this command must name a directory that already exists.  You can give the name using any absolute or relative naming method shown earlier.  A couple of restrictions on using this command include the directory named can not be the current working directory at the time you give the command to remove that directory, and the directory named can not have any children (no files or directories) besides the two default listings which are named  "." (dot to represent the current directory)  and ".." (dot-dot to represent the parent of the current directory) .  For examples click here.

meta-characters

            Several of the characters when used on the command line have a meta-meaning.  This means they have another meaning beyond being that character itself.  For example (as discussed above), the tilde "~" character will mean "the home of" as shown for naming files.  You may want to have a file whose name is actually "~this", but because the tilde will be assumed to mean "the home of" - it can't be done without special notation.  The alphabetic characters shown in this name are fine as they are because they do not have a meta-meaning on the shell.  All cha racters are allowed to be within a file or directory name except the forward slash "/"  -- it is just more difficult to deal with the ones that also have meta-meanings so we usually stick to the alphanumeric characters and the period to be within file and directory names. 

Several other characters also take on a meaning beyond the meaning of that character itself.    The most common of these are called the "wildcards".  Like the "wildcards" in the card game of poker, these characters are free and can stand in place for any other character needed with the individual meanings described below.  These characters are useful for example when you remember part of the name of the file or directory, but you do not remember the whole name.  You can give the parts you remember and then put the appropriate wildcard(s) in to replace the parts you do not remember.

wildcard

It means …

Examples

?

(the question mark)

replaces any one character at the point where the question mark appears

a?b a child of the current directory whose name starts with "a" and ends with "b" and has one and only one character between

??? a child of the current directory whose name is exactly three characters long (no more and no less)

/a?? a child of the root directory whose name is exactly three characters long (no more and no less) and the first is an "a"

*

(the star or asterisk)

replaces zero or more characters at the point where the star appears

a*b a child of the current directory whose name starts with "a" and ends with "b" and has zero or more characters between

*x a child of the current directory whose name ends in "x" (we know nothing else about that name)

/*a* a child of the root directory whose name contains at least one  "a" (we know nothing else about that name)

[]

(the square brackets)

replaces any one character at that point but only by one of the characters listed between the square brackets (a list without space or comma delimiters is used to indicate choices and the dash can be used to indicate a range according to the ASCII table)

a[xyz]b a child of the current directory whose name starts with "a" and ends with "b" and either an "x" or a "y" or a "z" between

[abc]x a child of the current directory whose name is exactly two characters long, ends in "x" and has either an "a" or a "b" or a "c" before the x

/[a-z][A-Z] a child of the root directory whose name is exactly two characters long where the first is a lowercase alphabetic character and the  second character is one of the uppercase alphabetic characters

/[ac-eg][1-5] a child of the root directory whose name is exactly two characters long where the first is either an "a" or a "c" or a "d" or an "e" or a "g" and the second character is either a "1" or a "2" or a "3" or a "4" or a "5"

{}

(the curly braces)

inserts any string specified within the braces at that point  (where the individual strings in the list are separated by commas)

a{xxx,yyy}b a child of the current directory whose name starts with "a" and ends with "b" and has either "xxx" or a "yyy"  between

{f1,g2}x a child of the current directory whose name is exactly three characters long, ends in "x" and has either an "f1" or a "g2" before the x

/{bob,dan}{f1,d2}a child of the root directory whose name has either "bob" or "dan" as the first three characters and either "f1" or "d2" as the last two characters

 

You can also mix the wildcards with in the name.  For example,  if you would like to specify a file in the current working directory whose name starts with an "a" and is followed by a numeric character and ends in the word "bob" or the word "fred" would be indicated by a[0-9]{bob,fred}

 

quoting to prevent interpretation of meta-characters

 

            If you would like to have a file or directory name that contains a character that has a meta-meaning, you need to prevent the shell from interpreting that file with its alternative meaning (in other words, to take the character as just that character itself).  There are several ways to do this.  This act of preventing the interpretation of the character's meta-meaning is called "quoting" - to quote means to take the characters literally.  One way to quote put quotation marks around the string of characters to be taken literally.  These can either be single quotes (also called apostrophes) or double quotes (also called quotation marks).  The single and double quotes are different in some cases, but we'll get to that when talking about shell variables.  The other way to quote is to put a backslash directly in front of the one character you would like quoted.  The single and double quotes must be used in pairs one beginning the area to be quoted and the other ending that area.  The backslash does not get used as a pair - rather just one immediately before the character to be quoted.

 

For example (assuming the names that start with a d are directories and the things that start with f are files):

% more "file*"

displays the contents of the file named file* which is a child of the current directory

% more 'file*'

displays the contents of the file named file* which is a child of the current directory

% more file\*

displays the contents of the file named file* which is a child of the current directory

% more a\?a

displays the contents of the file named a?a which is a child of the current directory

% more ?\??

displays the contents of all files whose names are exactly three characters long where the middle character is a question mark - note the first and last question marks are not quoted

% more ?\*\?*

displays the contents of all files whose names have a star as the second character and a question mark as the third character - note the first question mark and the last star are not quoted

 

 

using the ls command with arguments

 

            When the ls command is used, its argument can be a directory name or a file name.  If the argument is a directory, the content of that directory is listed, but if the argument is a file, the name of that file is listed (if is exists). This is useful when you want to see what children the named directory has.  It is useful to give a filename as the argument to the ls command when the list of the whole directory is very long.  It is usually more useful with wildcards because usually if you already know the full name, you can easily find it in the alphabetized list presented by the ls command.

 

For example (assuming the names that start with a d are directories and the things that start with f are files):

% ls dir1

lists the contents of the directory named dir1 which is a child of the current directory

% ls /dir2

lists the contents of the directory named dir2 which is a child of the root directory

% ls file1

lists the name of the file named file1 if it exists or nothing if it does not exist in the current working directory

% ls dir1/file2

lists the name of the file named file2 if it exists or nothing if it does not exist in the directory named dir1 which is a child of the current working directory

% ls dir1/f*2

lists the names of the files whose names start with an f and end with a 2 who are children of the directory named dir1 which is a child of the current directory

% ls d*2

lists the names of the children of the directories whose names begin with a d and end with a 2 which are children of the current working directory

 

 The above examples assume that files are named starting with "f" and directories are named starting with "d", but this is not a realistic.  If there are both files and directories which are children of the current directory whose names start with an "m", and you give the command

            % ls m*

it will list first the names of the files that match the criteria in the current directory, but then it will also list the contents of any directories whose names start with "m" which are children of the current directory.  This means you are getting both the list of children of the current directory that match the criteria as well as the listing of all grandchildren where their parent matches the criteria. 

To prevent the argument from being treated as a directory (and just see the listing of the children, not the grandchildren, you can  use the -d option on the ls command.  For an example click here.

 

the shell's ability to find what you request

            Whenever a command is given to the shell, it must find all of the parts mentioned on the command line.  This is done differently depending on the part of the command line in question.

            As discussed earlier for the arguments, the user must specify the location.  If the user wants to display the contents of a file named  this.file which is in the current directory, only the name is needed since the current directory is the default.  If  this.file is in the root directory (which is not the current directory at the time, the full name is required to specify the location: /this.file would be needed.  As one more option, if  this.file is in the home directory of the user named jplane, the complete name could be used starting from that home: ~jplane/this.file would specify that file.  The important thing to notice here is that the arguments to the commands are not searched for (in general).  There is a default (the current working directory) which is assumed if you do not explicitly say where the file or directory is located, but it always needs to be specified either explicitly (by typing it out)  or implicitly (using the default).

            For the command portion of the command line, the shell must also find the corresponding file.  In other words the computer is not "smart" -- it does not know how to do the things you give it commands to do -- it only knows how to follow directions.

Analogy: Like a chef taking orders at a restaurant who does not really know how to prepare the meals requested, every time an order is placed, he must look it up.  He pulls the correct cookbook off the shelf and proceeds to follow the directions given there in the cookbook.  With the number of different items available on the menu even knowing how to find the correct corresponding recipe is an achievement.

The shell must also find the directions, but how does it know where look.  There are so many different directories available and so many commands available to be given it would be impossible without some type of list.  This list of places to search is called the "command search path".  The command search path is held in a shell variable called path and is usually set for you as you log into your UNIX account (as the shell starts).  Each shell has setup files that are run as the shell starts and would give you the opportunity to personalize the shell, but if you don't have those files created, the system administrator would provide the shell with a default value of the command search path.  The path variable holds a list of places (directories) where the shell should look for the command.  It will look in all of the places in the list in the order specified by the list - searching for a command corresponding to what you have typed as the command portion of this command line.  For example if you have a command line that looks like:  % junk.cmd   it means you are trying to run the command known as junk.cmd.  It will look in all of the directories listed in the command search path for a file named junk.cmd and then use that file as directions to tell it what to do.  If it does not find a file, it will say unknown command or bad command, but only after it has looked in every one of the directories listed.  There is often another related shell variable named PATH which is called an "environmental variable" in that it will carry from one shell to a child of that shell.  Often the path variable and the PATH variable have the same or very similar content.  To see the contents of your search path use the command shown below, the output will be similar to what is shown.

% echo $PATH

/bin:/usr/bin:/sbin:/usr/sbin:usr/local/sbin

This means that for every command given, the shell will first look into the directory named bin that is a child of the root.  If it does not find the file there, it will look into the directory named bin that is a child of the directory named usr that is a child of the root.  It is is not found there, it looks into the directory named sbin which is a child of the root.  Notice the colon is used as the delimiter between the items in this list.

If the file that holds the commands you would like done is not in one of these directories, you can explicitly specify the location of the directions the same way as you specify the location of arguments.  For example the command line   % ./this.cmd would only look into the current directory for the file named this.cmd -- it would not look through the directories listed in the command search path.  In other words, if the command's location is explicitly stated, it does not need to search.

The other restriction is that the command named must be "executable".  This means that the user must have permission to execute that file as a command.  These permissions are set by the owner and the next unit will tell how to change permissions of the file and directories you own.

 

conversions between the different bases

Before we can talk about the permissions, we need to have a small unit here in the conversions of numeric values to different bases.    Everything in the computer is stored in binary form -- all that is in the computer is a series of bits where each bit is either on or off.  It converts these series of bits according to many different rules.  One of these is ASCII as it is used for ASCII text files.  If the file is representing other things though, other rules are used.  One of those is for numeric values.

As people learn to count, they typically learn what is called the decimal system (based on 10).  You can count 0 through 9, but then when you go to 10, you must add another column (or digit).  In other words when counting in based 10, you can put 10 different values in one digit place before you go to another column where you can also put any one of 10 different values in that column before you go to a third digit.

Since the computer uses binary (base 2), you can only have one of 2 different values in each digit place.  We often use 0 and 1 to represent those values  - the computer really thinks of them more as off and on.  Once you have gone through those two possible values, you must add another column.  So comparing decimal and binary:

decimal value

binary value

0

0

1

1

2

10

3

11

4

100

5

101

6

110

7

111

8 

1000

9

1001

10

1010

20

10100

21

10101

22

10110

30

11110

31

11111

32

100000

100

1100100

101

1100101

 

It doesn't take too large of values to realize how annoying working with binary would be for people.  Series of 1's and 0's that get to 7 places even before getting to the decimal value 100 are difficult for people to use. 
Converting between decimal and binary is not easy for larger numbers, using binary is not easy for people, but using binary is all the computer knows.  These three reasons are the motivation for the other two number systems used commonly in computer science.  Octal (base 8) and hexadecimal (base 16) are very common for computer scientists because octal and hexadecimal have fewer digits than binary (more like decimal), but it is easy to convert even very large binary numbers to either hexadecimal or octal.

All four of these number systems have one major thing in common.  It is the places are used to determine the actual contribution of a digit to the value of the whole number.  For example 7342 in decimal means there are 7 thousands, 3 hundreds, 4 tens and 2 ones.  This is most likely something you learned way back in elementary school.  You may not have learned why those values for the places were chosen.

The why has to do with the base of the number system the value is written using.  Since the 7342 given above is said to be in decimal, you have to interpret the places according to base 10.  This means that the place to the furthest right (for integer values) is the 100 place.  Since any number raised to the 0th power is 1, this is also known as the 1's place.  The next place to the left is the 101 place which is also known as the 10's place.  The next two are the 102 place and the 103 place which are the 100's (hundreds) and the 1000 (thousands) places respectively. 

This same thing can be applied to the binary system as long as the correct base is used.  This means that the value 1011 in binary has a 1 in the place furthest to the right which is the 20 (or 1's place).  It then has a 1 in the 21 (or 2's place), a 0 in the 22 (or 4's place), and a 1 in the 23 (or 8's place).  Adding these values up is an easy way to convert values from any base to their corresponding values in decimal.


decimal

binary

octal

7342  base 10

1011  base 2

1427  base 8

(7 * 103)   + (3 * 102)  + (4 * 101) + (2 * 100)

(1 * 23) + (0 * 22) + (1 * 21) + (1 * 20)

(1 * 83)   + (4 * 82) + (2 * 81) + (7 * 80)

(7 * 1000) + (3 * 100) + (4 * 10)  + (2 * 1)

(1 * 8)  + (0 * 4)  + (1 * 2)   + (1 * 1)

(1 * 512) + (4 * 64) + (2 * 8)  + (7 * 1)

7000         + 300         +   40        + 2

8          +  0         +  2          + 1

512         +  256      +  16        + 7

7342  base 10

11  base 10

791  base 10

 

            The same process can also be used with hexadecimal, the only additional consideration is that we need to be able to represent the 16 values between 0 and 15 as one digit.  With the digits from base 10 that is not possible -- 0 through 9 is possible in one digit, but numbers larger than that require two digits.  In hexadecimal we then use the letters of the alphabet to represent the numbers between 10 and 15 inclusively.  So in hexadecimal the following values can be represented as one digit.

decimal

hexadecimal

 

Conversion examples

0

0

 

1032   base 16

1

1

 

(1 * 16^3)+ ( 0 * 16^2) + (3 * 16^1) + (2 * 16^0)

2

2

 

(1 * 4096)  +  (0 * 256) + (3 * 16)  + (2 * 1)

3

3

 

4096          + 0              + 48          + 2

4

4

 

4146      base 10

5

5

 

 

6

6

 

          and

7

7

 

 

8

8

 

A21B     base 16

9

9

 

(A * 16^3)+ ( 2 * 16^2) + (1 * 16^1) + (B * 16^0)

10

A

 

(10 * 16^3) + ( 2 * 16^2) + (1 * 16^1) + (11 * 16^0)

11

B

 

(10 * 4096)  + ( 2 * 256) + (1 * 16)  + (11 * 1)

12

C

 

40960         + 512          + 16          + 11

13

D

 

41499      base 10

14

E

 

 

15

F

 

 

 

            When converting the other direction (base 10) to any other base, you need to use repeated integer division by the destination's base  rather than the multiplication shown above.  Integer division is when you divide an integer by an integer and then get a quotient  and a remainder.  The remainders are what is needed to fill into the appropriate places of the number being created.  If you take the octal value 791 and want to know its equivalent value in decimal, you would repeatedly divide by 8.    Notice the remainder of dividing by 8 would have to be a value between 0 and 7 inclusively (which are the valid digits for the octal number).  You continue dividing until you have a 0 to divide (since 0 divided by any value is 0 with remainder 0).

mathematical problem

quotient

remainder

791 divided by 8

98

7

98 divided by 8

12

2

12 divided by 8

1

4

1 divided by 8

0

1

0 divided by 8

DONE

 

            This means that 791 base 10 equals 1427 base 8 (taking the remainders in the reverse order).  Click here for more examples.

           

            Converting between  binary and either hexadecimal or octal is even easier than having to involve decimal values in the conversion.  This is because octal is base 8 and 8 is 2 raised to the third power and hexadecimal is base 16 and 16 is 2 to the fourth power.  Because 8 is 2 to the third power (2*2*2), when converting we can know for sure that any 3 binary digits can uniquely be converted to 1 octal digit and any octal digit can uniquely convert to 3 binary digits.  Because 16 is 2 to the fourth power (2*2*2*2), when converting we can know for sure that any 4 binary digits can uniquely be converted to 1 hexadecimal digit and any hexadecimal digit can uniquely convert to 4 binary digits.  In other words if he have a very large binary number, we can break it into groups of either 3 or 4 and never have to go into the higher powers of 2.

 

 

octal

hexadecimal

binary

101111010011 (base 2)

101111010011  (base 2)

split into groups

101  111  010  011

1011   1101   0011

each digit

 5    7    2    3   

 11     12      3

value in the new base

5723   (base 8)

BC3   (base 16)

 

file/directory access permissions

ls -l command

            The access permissions for each file and directory can be displayed by using the -l option  of the ls command.  Like the other uses of the ls command, the contents of the current or named directory is listed to the screen.  This output is different from the ls command without an option because much more information is given about each of the things in the list.  The information that is usually displayed includes:

  1. type
  2. permissions
  3. number of links
  4. owner's id
  5. group name (on some machines)
  6. size in bytes
  7. modification date and time
  8. name

 

The output looks similar to the following (this example is color coded to make the parts easier to discern):

% ls -l

drwx--x--x  2 jplane  cmsc106      512 Jan 22 08:46 106

-rwxr-xr-x  1 jplane  students     512 Mar 14 21:19 a.calling

-rw-r--r--  1 jplane  research    1024 Apr 27 23:07 exam2.answers

 

1.      The type is indicated by a single letter.  The "d" indicates that the item displayed on that line is a directory.  The "-" indicates that it is a regular file.  Other things that could appear include a "l" to indicate a symbolic link (described later in this file) or a "s" to indicate a socket.

2.      The permissions is indicated by a sequence of 9 characters.  The 9 characters are actually 3 groups of permissions where each permission is for one part of the community and each community needs three characters to represent its permissions.  The first set of 3 characters tells the permissions of the owner of the item (also called the "user").  The second set of three represents the permissions of the group with which this file is associated.  The third set tells the permissions associated with the rest of the people who have access to this computer (called either the "world" or the "others").  Within each of these sets there are three characters.  The first character tells if that portion of the community has read permissions, the second tells if they have write permissions and the third tells if they have execute permission.  For each of these characters, if that group has that permission, the appropriate character (r, w or x) will be shown. If they do not have that permission, it will be shown as a dash.

3.      The number of links is indicated by a positive integer.  For files it tells how many other ways there are to get to this file (if there are alternative names possibly in other parts of the directory structure.

4.      The owner's id  tells the login id of the person who owns the item.  This usually indicates the person who created the item, but can be changed after the item has already been created by using the chown command.

5.      The group name tells the name of the group with which the item is associated.  When a user creates something, it is associated with his default group, but it can be changed by using the chgrp command or the chown command.

6.      The size in bytes tells the size of the file in bytes.

7.      The modification date and time tells the last modification date and time.  If it has been over a year since the last modification, the time is replaced by the year.

8.      The name is the same as what you would have seen if you had just done a regular ls without the -l option.

chmod command

            The chmod command is used to change the permissions.  You can only use this command to change the permissions on something you own.  The word chmod stands for "change mode", and it allows you to set any of the 9 permission characters shown in the ls -l output.  The command is usually used with 2 arguments.  The first argument tells how you would like the permissions changed and the second tells what file or directory you would like to change the permissions of.  The name of the file or directory can have wildcards and refer to a whole list of files and or directories or it can just be the name of a single file or directory.  The specification of the permissions can be done two different ways.  One way is called absolute because it specifies explicitly what all of the permission characters should be, and the other way is called relative because it can be used to change some of the permissions but not all - the result is then relative to what the permissions were before the command was given.

            The absolute change method is why it is important to understand conversions between different bases of numbers.  This first argument to the chmod command needs to be a series of three octal digits.  Each of these octal digits tells the permissions for one group of people.  Remember the permissions section of the ls -l command told the access for the user, the group and the rest of the world (in that order).  The 9 permission characters can be viewed as 9 distinct bits where each bit is either turned on or off.  So a series of 9 binary digits can be converted to a series of 3 octal digits by the method above. The following table shows the process for converting the desired permissions to their corresponding octal digits.

Permissions

Desired on the file this.file

Owner/user

permissions

Group

permissions

World/Other

permissions

Command to achieve those permissions

rwxrw-r--

rwx = 111 = 7

rw- = 110 = 6

r-- = 100 = 4

% chmod 764 this.file

r-xr-----

r-x = 101 = 5

--x = 001 = 1

--- = 000 = 0

% chmod 510 this.file

rw-rw-rw-

rw- = 110 = 6

rw- = 110 = 6

rw- = 110 = 6

% chmod 666 this.file

 

            The relative change method uses three distinct parts within the one argument that specifies the permissions.  All three parts must be within the first argument.  This means there can be no spaces since a space would indicate the end of that argument.  The first part tells whose permission will be changed, the second part tells if you are adding, subtracting or setting those permissions; the third part tells if you are changing the read, write or execute permission.   The values available for the three parts are shown in the table below.

 

Whose permission are changing

How they are changing

Which permission for that group is changing

u     is user or owner

+      is add these permissions

r      is read permission

g      is group

-       is remove these permissions

w     is write permission

o      is other or world

=      is set these permissions

x      is execute permission

a      is all

 

 

 

In the following table assume the left column tells the command used to change the permissions of the file named this.file and the right column tells what the permissions would become.  Any permissions that are not dependant on what the permissions were before the command were given are shown as question mark "?" because they would be the same as they were before the command.

Command to change permissions

What the permissions become

% chmod u+x    this.file

??x??????

% chmod o-rwx  this.file

??????---

% chmod a+r    this.file

r??r??r??

% chmod g+rwx  this.file

???rwx???

% chmod u=rw   this.file

rw-??????

% chmod go=rx  this.file

???r-xr-x

           

            When these permissions are applied to a file, each one means the ability to do some specific task to that file.  The read permission means you have the ability to display (or read) the contents of that file.  The write permission means you can modify the contents of that file.  The execute permission means that you can use that file as a command, and thus, run (or execute) the file.  In order to access any file though, you do need to have permission to access the appropriate permissions to the directory in which the file is located.

            When these permissions are applied to a directory, they have slightly different meanings.  The read permission means that you can list the contents of that directory - such as doing and ls of that directory or using anything else that would tell you the names of that directory's children.  The write permission means that you can modify the contents of that directory - such as deleting a file that is in the directory or creating a new file that would be in the directory.  The execute permissions are the most different; this means that you can go into that directory -such as doing a cd into that directory or using the files or subdirectories in that directory.

            Notice, that this combination of levels means that in order to display the contents of a file named file.1 that is in a directory named dir.1, you would need to have execute permissions on the directory named dir.1 and read permissions on the file named file.1.

 

creating additional links and symbolic links

            The link number (shown as the third piece of information from the left in the ls -l output) tells how many different names correspond to that file.  In other words it is 1 when you create a file because it has only the name you gave it at the time of creation, but you can then create alternative names that refer to the same space in memory.  Remember a file is just a sequence of bits which is stored somewhere in the computer's memory - the name is just the connection of how to get to that place (translates to that space's address).  If two files both have a 2 as their link number when you do an ls -l command, you can not assume that they are alternative names for each other.  All you can know from this information is that each has an alternative name somewhere.

            To know if they are indeed links to the same exact space in memory (the same file space) you would need know see something that tells you more about the address the names each translate to. This is called the i-node number.  To see the i-node number, use the -i option of the ls command. 

shell command and output

what the output means

% ls -i

122754    this.file

132321    that.file

122754    other.file

The two names this.file and other.file do refer to the same space in memory.

The two name that.file refers to a different space.

 

            If you look at all three files using the more command for example, they could have the same content for example.  If the content of that.file is modified, the other two will not change, but if the content of this.file is modified, the content of other.file will be modified in exactly the same way.

 

Graphically this information can be viewed as:

 

 

            When ever you create a file using the copy command or by using any tool or application, a first link is created to the space in memory where that information is stored.  It is given a unique i-node number to indicate the space in which that file is stored in memory.    There are two options for creating alternate names - both of these options use the ln command to create the second link to an already allocated space.  The two options are called a hard link and a  soft (or symbolic) link.

            The number of hard links is indicated by the link number shown in the ls -l command.  The hard links are created by using the ln command without any options.   The arguments to the ln command, like the arguments to the cp command, are a "from where" and a "to where" sequence.  The "from where" must be a file that already exists and the "to where" is what will come into existence.  If the "to where" already exists, its contents will most likely be lost.  The new link created is an alternative name for the file named as the first argument.  These two links can be in the same directory, but don't need to be.  These two links have the same access to the space in memory - either can be used equally well, and using either takes you to that same space in memory.

            The number of soft (or symbolic) links is not indicated by the link number in the output of the ls -l command.  That is because a symbolic link does not have the same standing or access to the file.  It will appear in many cases to be an alternative name to the same space, but it is more like a "nickname" rather than a second official name.  The symbolic link is made by using the ln -s command. With this command, the first argument is a file or a directory that already exists and the second is the "nickname" by which you would like to refer to that space.  Symbolic links were first only a part of Berkeley variations of UNIX, but has become more common in other variations as well.

            The differences between the hard and symbolic links are shown in the table below:

 

Hard Link Characteristics

Symbolic Link Characteristics

To create one:

% ln old.file new.name

% ln -s old.file new.name

Access:

removing either link is fine (with the rm command) because the space in memory will be available through the other link

removing the original actual link will make the "nickname" or symbolic link unusable because the system needs to translate the "nickname" to a real name in order to find the appropriate space in memory

ls -l output

the number of symbolic links is shown by the link number, but there is no way with the ls -l output to tell what two filenames refer to the same space

the type of item (first character of the ls -l output line) is an l for a symbolic link

the file name (on the far right side) connects this nickname to its actual name

ls -i output

the i-node number will be the same for two names that are actually hard links to the same space

the i-node numbers will be different since the actual name's i-node number tells where the file space itself is located and the symbolic link's i-node number give directions on how to translate to the actual hard link's name

 

     

symbolic links between directories are also possible hard links are not

When a symbolic link is created for a directory, it will act like a slide (when you get on the top end of the slide, you are immediately taken to the bottom end of the slide).  When you go into what appears to be the child of a directory, you could actually get into a completely different part of the tree.  This is often used when a directory you want to use frequently is many levels down in the tree, but you don't want to type its complete name on a regular basis.  You can create a symbolic link so that the directory that is many levels down in actuality appears as if it is a child of the current working directory.  If you want to find out what directory is current, there is two different commands which will give different results if there are symbolically linked directories involved.

% pwd

will tell you the hard link name (path) to the space you are in

 

% echo $cwd  

will tell the symbolic name (path)