system software lab vi sem ise

34
System Software Laboratory Manual Dept. Of I. S. E. 1 K.L.E.I.T-HUBLI PART - A LEX AND YACC PROGRAMS: Execute the following programs using LEX: 1) a. Program to count the number of characters, words, spaces and lines in a given input file. b. Program to count the numbers of comment lines in a given C program. Also eliminate them and copy the resulting program into separate file. 2) a. Program to recognize a valid arithmetic expression and to recognize the identifiers and operators present. Print them separately. b. Program to recognize whether a given sentence is simple or compound. 3) Program to recognize and count the number of identifiers in a given input file. Execute the following programs using YACC: 4) a. Program to recognize a valid arithmetic expression that uses operators +, -, * and /. b. Program to recognize a valid variable, which starts with a letter, followed by any number of letters or digits. 5) a. Program to evaluate an arithmetic expression involving operators +, -, * and /. b. Program to recognize strings ‘aaab’, ‘abbb’, ‘ab’ and ‘a’ using the grammar (a n b n , n>= 0). 6) Program to recognize the grammar (a n b, n>= 10). PART - B Unix Programming: 1) a. Non-recursive shell script that accepts any number of arguments and prints them in the Reverse order, (For example, if the script is named rargs, then executing rargs A B C should produce C B A on the standard output). b. C program that creates a child process to read commands from the standard input and execute them (a minimal implementation of a shell – like program). You can assume that no arguments will be passed to the commands to be executed. 2) a. Shell script that accepts two file names as arguments, checks if the permissions for these files are identical and if the permissions are identical, outputs the common permissions, otherwise outputs each file name followed by its permissions. b. C program to create a file with 16 bytes of arbitrary data from the beginning and another 16 bytes of arbitrary data from an offset of 48. Display the file contents to demonstrate how the hole in file is handled.

Upload: raghavendra-kalaghatagi

Post on 24-Mar-2015

279 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: System Software Lab VI Sem ISE

System Software Laboratory Manual

Dept. Of I. S. E.

1

K.L.E.I.T-HUBLI

PART - A

LEX AND YACC PROGRAMS: Execute the following programs using LEX: 1) a. Program to count the number of characters, words, spaces and lines in a given

input file. b. Program to count the numbers of comment lines in a given C program. Also

eliminate them and copy the resulting program into separate file. 2) a. Program to recognize a valid arithmetic expression and to recognize the

identifiers and operators present. Print them separately. b. Program to recognize whether a given sentence is simple or compound.

3) Program to recognize and count the number of identifiers in a given input file.

Execute the following programs using YACC: 4) a. Program to recognize a valid arithmetic expression that uses operators +, -, *

and /. b. Program to recognize a valid variable, which starts with a letter, followed by any

number of letters or digits. 5) a. Program to evaluate an arithmetic expression involving operators +, -, * and /. b. Program to recognize strings ‘aaab’, ‘abbb’, ‘ab’ and ‘a’ using the grammar (anbn, n>= 0).

6) Program to recognize the grammar (anb, n>= 10).

PART - B Unix Programming:

1) a. Non-recursive shell script that accepts any number of arguments and prints them

in the Reverse order, (For example, if the script is named rargs, then executing rargs A B C should produce C B A on the standard output).

b. C program that creates a child process to read commands from the standard input and execute them (a minimal implementation of a shell – like program). You can assume that no arguments will be passed to the commands to be executed.

2) a. Shell script that accepts two file names as arguments, checks if the permissions for

these files are identical and if the permissions are identical, outputs the common permissions, otherwise outputs each file name followed by its permissions.

b. C program to create a file with 16 bytes of arbitrary data from the beginning and

another 16 bytes of arbitrary data from an offset of 48. Display the file contents to demonstrate how the hole in file is handled.

Page 2: System Software Lab VI Sem ISE

System Software Laboratory Manual

Dept. Of I. S. E.

2

K.L.E.I.T-HUBLI

3) a. Shell function that takes a valid directory names as an argument and recursively

descends all the subdirectories, finds the maximum length of any file in that hierarchy and writes this maximum value to the standard output.

b. C program that accepts valid file names as command line arguments and for each

of the arguments prints the type of the file (Regular file, Directory file, Character special file, Block special file, Symbolic link etc.)

4) a. Shell script that accepts file names specified as arguments and creates a shell

script that contains this file as well as the code to recreate these files. Thus if the script generated by your script is executed, it would recreate the original files(This is same as the “bundle” script described by Brain W. Kernighan and Rob Pike in “ The Unix Programming Environment”, Prentice – Hall India).

b. C program to do the following: Using fork( ) create a child process. The child

process prints its own process-id and id of its parent and then exits. The parent process waits for its child to finish (by executing the wait( )) and prints its own process-id and the id of its child process and then exits.

5) a. Shell script that accepts path names and creates all the components in that

pathnames as directories. For example, if the script name is mpe, then the command mpe a/b/c/d should create directories a, a/b, a/b/c, and a/b/c/d.

b. C program that accepts one command-line argument, executes the arguments as a

shell command, determines the time taken by it and prints the time values, Use the “times”, function and the “tms” structure. The code need not include error checking.

6) a. Shell script that accepts valid login names as arguments and prints their

corresponding home directories. If no arguments are specified, print a suitable error message.

b. C program that accepts a valid directory names as a command line argument and

lists all the files in the given directory as well as all the subsequent subdirectories. (The solution can be recursive or non-recursive).

7) a. Shell script to implement terminal locking. It should prompt the user for a

password. After accepting the password entered by the user, it must prompt again for password confirmation (to retype the password). If a match occurs, it must lock the terminal and prompt for the password. If the proper password is entered, the terminal must be unlocked. Note the script must be written to disregard BREAK, Control-D etc. No time limit need be implemented for the lock duration.

b. C program to prompt the user for the name of an environment variable and

print its value if it is defined and a suitable message otherwise; and to repeat the process if user wants it.

Page 3: System Software Lab VI Sem ISE

System Software Laboratory Manual

Dept. Of I. S. E.

3

K.L.E.I.T-HUBLI

1. Lex Introduction

The word “lexical” in the traditional sense means pertaining to words. In terms of programming languages, words are objects like variable names, numbers, keywords etc. Such words are traditionally called tokens. A lexical analyzer, or lexer for short, will take input as a string of individual letters and divide this string into tokens. Additionally, it will filter out whatever separates the tokens (the so-called white-space), i.e., layout characters (spaces, new lines etc.) and comments. The lexical analyzer is the first phase of a compiler. Its main task is to read the input characters and produce as output a sequence of tokens that the parser uses for syntax analysis. This interaction, summarized schematically in Fig1.1, is commonly implemented by making the lexical analyzer be a subroutine or a co routine of the parser.

Fig.1.1 Interaction of lexical analyzer with parser

1.1 A Language for Specifying Lexical Analyzer

Several tools have been built for constructing lexical analyzers from special purpose notations based on regular expressions. In this section, we describe a particular tool, called Lex that has been widely used to specify lexical analyzers for a variety of languages. We refer to the tool as Lex compiler, and its input specification as the Lex language. Lex is generally used in the manner depicted in Fig 1.2. First, a specification of a lexical analyzer is prepared by creating a program lex.l in the lex language. Then, lex.l is run through the Lex compiler to produce a C program lex.yy.c. The program lex.yy.c consists of a tabular representation of a transition diagram constructed from the regular expression of lex.l, together with a standard routine that uses the table to recognize lexemes. The actions associated with regular expression in lex.l are pieces of C code and are carried over directly to lex.yy.c. Finally lex.yy.c is run through the C compiler to produce an object program a.out, which is the lexical analyzer that transforms an input stream into a sequence of tokens.

Page 4: System Software Lab VI Sem ISE

System Software Laboratory Manual

Dept. Of I. S. E.

4

K.L.E.I.T-HUBLI

Fig 1.2 creating a lexical analyzer with Lex

Lex specifications (Source) A Lex program consists of three parts: The general format of Lex source is:

{definitions}

%%

{rules}

%%

{user subroutines}

The declarations section includes declarations of variables, constants, and regular definitions. The rules of a lex program are statements of the form

R1 {action1}

R2 {action2}

.... .... Rn {action n} where each Ri is regular expression and each action i, is a program fragment describing what action the lexical analyzer should take when pattern Ri matches lexeme. Typically, action i will return control to the parser. In Lex actions are written in C; in general, however, they can be in any implementation language. The third section holds whatever auxiliary procedures are needed by the actions.

1.2 The Role of a Parser

The parser obtains a string of tokens from the lexical analyzer and verifies that the string can be generated by grammar for the source language. We expect the parser to report any syntax errors in an intelligible fashion. It should also recover from commonly occurring errors so that it can continue processing the remainder of its

Page 5: System Software Lab VI Sem ISE

System Software Laboratory Manual

Dept. Of I. S. E.

5

K.L.E.I.T-HUBLI

input. We know that programs can contain errors at many different levels. For example, errors can be

1. Lexical, such as misspelling an identifier, keyword or operator. 2. Syntactic, such as arithmetic expression with unbalanced parentheses 3. Semantic, such as an operator applied to an incompatible operand. 4. Logical, such as infinitely recursive call.

Often much of the error detection and recovery in a compiler is centered around the syntax analysis phase.

1.3 LEXICAL CONVENTIONS The notations for specifying tokens: 1. . Matches any single character except the new line (.\n.) 2. * Matches zero or more copies of the preceding expression. 3. [ ] A character class which matches any character within the brackets. 4. ^ Matches the beginning of a line as the first character of a regular expression. 5. $ Matches the end of line as the last character of a regular expression. 6. \ Used to escape met character. 7. + Matches one or more occurrence of the preceding regular expression. For example [0-9]+ matches .12.,.9..but not an empty string. 8. ? Matches zero or one occurrence 9. | Matches either the preceding regular expression or the following expression. For example are | is | because matches any three words. 10. / Matches the preceding regular expression but only if followed by the regular expression. 11. ( ) Groups of series of regular expressions together into a new regular expression. 12. Blanks between tokens are optional, with the exception that keywords must be

surrounded by blanks, new lines, the beginning of the program or the final dot.

Page 6: System Software Lab VI Sem ISE

System Software Laboratory Manual

Dept. Of I. S. E.

6

K.L.E.I.T-HUBLI

1a. Program to count the number of characters, words, spaces and lines in a given

input file. %{ int ch=0,sp=0,wd=0,ln=0; %} %% [\n] {ln++;} /*For counting the line*/ [^ \t\n ]+ {ch+=yyleng,wd++;} /*For the character and words*/ " " {sp++;} /*For counting the space*/ %%

int main(int argc,char *argv[]) {

if(argc>1) yyin=fopen(argv[1],"r"); else yyin=stdin; yylex(); printf("Number of characters:%d\n",ch); printf("Number of spaces:%d\n",sp); printf("Number of words:%d\n",wd); printf("Number of lines:%d\n",ln);

}

OUTPUT

[root@localhost ~]# lex pgm1a.l [root@localhost ~]# cc lex.yy.c -ll [root@localhost ~]# ./a.out data.txt Number of characters: 14 Number of spaces: 0 Number of words: 2 Number of lines: 2

Page 7: System Software Lab VI Sem ISE

System Software Laboratory Manual

Dept. Of I. S. E.

7

K.L.E.I.T-HUBLI

1b. Program to count the numbers of comment lines in a given C program. Also

eliminate them and copy the resulting program into separate file. %{ int comment=0; %} %% "/*"[\n]*.*[\n]*"*/" {comment++;} /*For counting the comment*/ "/*"[\"*/"]* { fprintf(yyout," "); } /*For eliminate */ %% int main() { char infile[256],outfile[256]; printf("Enter the input filename:\n"); scanf("%s",infile); printf("Enter the output filename:\n"); scanf("%s",outfile); yyin=fopen(infile,"r"); yyout=fopen(outfile,"w"); yylex(); printf("Number of comment lines in the given file: %d\n",comment);

}

OUTPUT [root@localhost ~]# lex pgm1b.l [root@localhost ~]# cc lex.yy.c -ll [root@localhost ~]# ./a.out Enter the input filename: sum.c Enter the output filename: add.c Number of comment lines in the given file: 2

Page 8: System Software Lab VI Sem ISE

System Software Laboratory Manual

Dept. Of I. S. E.

8

K.L.E.I.T-HUBLI

2a. Program to recognize a valid arithmetic expression and to recognize the

identifiers and operators present. Print them separately.

%{ int count=0,ids=0,bracket=0; %} %% [+] {printf("+");count++;} [-] {printf("-");count++;} [*] {printf("*");count++;} [/] {printf("/");count++;} [a-zA-Z0-9]+ {ids++ ;printf(“%c”,yytext;} /*For recognizing the identifiers*/ [(] {bracket++ ;} [)] {bracket-- ;} %% int main() {

printf("Enter the Arithmetic expression:\n"); yylex(); printf("Number of Operators=%d\n",count); printf("Number of Identifiers=%d\n",ids); if(count>=ids||bracket!=0||ids==1) printf("Invalid expression\n"); else printf("Valid expression\n");

}

OUTPUT

[root@localhost ~]# lex pgm2a.l [root@localhost ~]# cc lex.yy.c -ll [root@localhost ~]# ./a.out Enter the Arithmetic expression: 2+3*4 +* (Press Ctrl d) Number of Operators=2 Number of Identifiers=3 Valid expression Enter the Arithmetic expression: 2+3*4- +*- (Press ctrl d) Number of Operators=3 Number of Identifiers=3 Invalid expression

Page 9: System Software Lab VI Sem ISE

System Software Laboratory Manual

Dept. Of I. S. E.

9

K.L.E.I.T-HUBLI

2b. Write a lex program to recognize whether a given sentence is simple or

compound.

%{

int flag=0; %} %% [a-zA-z]/(" "[aA][nN][dD]" ")|(" "[oO][rR]" ")|(" "[bB][uU][tT]" ") { flag=1; } . ; %% main() {

printf("\nEnter the sentence:"); yylex(); if(flag==1) { printf("Compund sentence\n"); } else { printf("Simple Sentence\n"); }

}

OUTPUT

[root@localhost ~]# lex pgm2b.l [root@localhost ~]# cc lex.yy.c -ll [root@localhost ~]# ./a.out Enter the sentence: abc is alphabet Given sentence is simple statement [root@localhost ~]# ./a.out Enter the sentence: abc or 123 are not equal Given sentence is compound statement

Page 10: System Software Lab VI Sem ISE

System Software Laboratory Manual

Dept. Of I. S. E.

10

K.L.E.I.T-HUBLI

3. Program to recognize and count the number of identifiers in a given input file.

%{

int count=0; %} %% ("int ")|("float ")|("double ")|("char ") {

int ch; ch=input();

for(;;) { if(ch==',')

{count++;} else if(ch==';')

{ count++; break;

} ch = input(); }}

%% int main(int argc, char *argv[]) { yyin=fopen(argv[1],"r"); yylex(); printf("no of identifiers are%d\n",count); } OUTPUT [root@localhost root]# lex pgm3.l [root@localhost root]# cc lex.yy.c -ll [root@localhost root]# ./a.out sum.c main() { int a,b; float c; } Number of identifiers are 3

Page 11: System Software Lab VI Sem ISE

System Software Laboratory Manual

Dept. Of I. S. E.

11

K.L.E.I.T-HUBLI

2. YACC Introduction

The unix utility yacc (Yet Another Compiler Compiler) parses a stream of token, typically generated by lex, according to a user-speciÞed grammar.

2.1 Structure of a yacc file A yacc File looks much like a lex file:

definitions

%%

rules

%%

Code Definition: All code between %{ and %} is copied to the beginning of the resulting C file. Rules: A number of combinations of pattern and action: if the action is more than a single command it needs to be in braces. Code: This can be very elaborate, but the main ingredient is the call to yylex, the lexical analyzer. If the code segment is left out, a default main is used which only calls

yylex.

Definition section

There are three things that can go in the deÞnitions section: C code: Any code between %{ and %} is copied to the C file. This is typically used for defining file variables, and for prototypes of routines that are defined in the code segment. Definitions: The definition section of a lex file was concerned with characters; in yacc this is tokens. Example: %token NUMBER. These token definitions are written to a .h file when yacc compiles this file. Associatively rules These handles associatively and priority of operators.

2.2 Lex Yacc interaction

Conceptually, lex parses a File of characters and outputs a stream of tokens; yacc accepts a stream of tokens and parses it, performing actions as appropriate. In practice, they are more tightly coupled. If your lex program is supplying a tokenizer, the yacc program will repeatedly call the yylex routine. The lex rules will probably function by calling return everytime they have parsed a token.

If lex is to return tokens that yacc will process, they have to agree on what tokens there are. This is done as follows :

For Example 1. The yacc File will have token deÞnition %token NUMBER in the definitions section.

Page 12: System Software Lab VI Sem ISE

System Software Laboratory Manual

Dept. Of I. S. E.

12

K.L.E.I.T-HUBLI

2. When the yacc File is translated with yacc .d, a header File y.tab.h is created that has definitions like #define NUMBER 258. 3. The lex File can then call return NUMBER, and the yacc program can match on this token.

2.3 Rules section The rules section contains the grammar of the language you want to parse. This looks like statement : INTEGER ‘=’ expression

| expression

;

expression : NUMBER ‘+’ NUMBER

| NUMBER ‘-‘ NUMBER

;

This is the general form of context-free grammars, with a set of actions associated with each matching right-hand side. It is a good convention to keep non-terminals (names that can be expanded further) in lower case and terminals (the symbols that are finally matched) in upper case. The terminal symbols get matched with return codes from the lex tokenizer. They are typically defines coming from %token definitions in the yacc program or character values.

2.4 Compiling and running a simple parser On a UNIX system ,yacc takes your grammar and creates y.tab.c ,the C Language parser, and y.tab.h, the include file with the token number definitions. Lex creates lex.yy.c,the C language lexer .You need only compile them together with the yacc and lex libraries. The Libraries contain usable default versions of all of the supporting routines, including main ( ) that calls the parser yyparse( ) and exits. [root@localhost ~]# lex filename.l #makes lex.yy.c [root@localhost ~]# yacc -d filename.y #makes y.tab.c and y.tab.h [root@localhost ~]# cc lex.yy.c y.tab.c –ll #compile and link C files [root@localhost ~]# ./a.out

Page 13: System Software Lab VI Sem ISE

System Software Laboratory Manual

Dept. Of I. S. E.

13

K.L.E.I.T-HUBLI

4a. Program to recognize a valid arithmetic expression that uses operators +, -, *

and /.

Lex program

%{ #include "y.tab.h" %} %% [a-zA-Z][a-zA-Z0-9]* {return ID;} [0-9]+ {return NUMBER;} . {return yytext[0];} \n {return 0;} /*Logical EOF*/ %%

Yacc progarm

%token NUMBER ID /*token definition*/ %left '+''-' /*Operator precedence’s*/ %left '*''/' /*Operator precedence’s*/ %% expr:expr '+' expr; |expr '-' expr; /*Grammar*/ |expr '*' expr; |expr '/' expr; |'('expr')' |NUMBER |ID ; %% int main() { printf("Enter the Expression\n"); yyparse(); printf("Valid Expression\n"); } int yyerror() { printf("Expression is invalid\n"); exit(0); }

OUTPUT [root@localhost ~]# lex pgm4a.l [root@localhost ~]# yacc -d pgm4a.y [root@localhost ~]# cc lex.yy.c y.tab.c -ll [root@localhost ~]# ./a.out

Run1 Run2

Enter the Expression Enter the Expression +23 2+3-4 Expression is invalid Valid Expression.

Page 14: System Software Lab VI Sem ISE

System Software Laboratory Manual

Dept. Of I. S. E.

14

K.L.E.I.T-HUBLI

4b. Program to recognize a valid variable, which starts with a letter, followed by

any number of letters or digits.

Lex program

%{ #include"y.tab.h" %} %% [0-9] {return DIG;} [a-z] {return LET;} . {return yytext[0];} \n {return 0;} /*Logical EOF*/ %%

Yacc program

%token LET %token DIG %% stmt:id {printf("Valid identifier \n");} ; id: letter next | letter {;} ; next: letter next | digit next | letter | digit {;} ; letter: LET {;} ; digit: DIG {;} ; %% int main() { printf("Enter an identifier:"); yyparse(); } int yyerror() { printf("Not a valid identifier\n"); exit(0); }

OUTPUT [root@localhost ~]# lex pgm4b.l [root@localhost ~]# yacc -d pgm4b.y [root@localhost ~]# cc lex.yy.c y.tab.c -ll [root@localhost ~]# ./a.out

Run1 Run2

Enter an identifier: ab12 Enter an identifier: 12dc Valid identifier Not a valid identifier

Page 15: System Software Lab VI Sem ISE

System Software Laboratory Manual

Dept. Of I. S. E.

15

K.L.E.I.T-HUBLI

5a. Program to evaluate an arithmetic expression involving operators +, -, * and /.

Lex program

%{ #include"y.tab.h" extern int yylval; %} %% [0-9]+ {yylval=atoi(yytext); return(NUM);} [ \t] ; /*Ignore the whitespace*/ . {return yytext[0];} \n {return 0;} %%

Yacc program

%token NUM %left '+''-' %left '*''/' %% stmt : expr { printf("Result:%d\n",$1);return 0; } ; expr :expr'+'expr {$$=$1+$3;} | expr'-'expr {$$=$1-$3;} | expr'*'expr {$$=$1*$3;} | expr'/'expr { if($3==0) { printf("Divide by zero error\n"); exit(0); } else $$=$1/$3; } | '('expr')' {$$=$2;} | NUM {$$=$1;} ; %% int main() {

Page 16: System Software Lab VI Sem ISE

System Software Laboratory Manual

Dept. Of I. S. E.

16

K.L.E.I.T-HUBLI

printf("Enter the expression\n"); yyparse(); } int yyerror() { printf("Invalid input\n"); exit(0); }

OUTPUT [root@localhost ~]# lex pgm5a.l [root@0localhost ~]# yacc -d pgm5a.y [root@localhost ~]# cc lex.yy.c y.tab.c -ll [root@localhost ~]# ./a.out

Run1

Enter the expression 2+3 Result: 5

Run2 Enter the expression (2*3)+4 Result: 10

Page 17: System Software Lab VI Sem ISE

System Software Laboratory Manual

Dept. Of I. S. E.

17

K.L.E.I.T-HUBLI

5b. Program to recognize strings ‘aaab’, ‘abbb’, ‘ab’ and ‘a’. Using the grammar

(anbn, n>= 0).

Lex program

%{ #include"y.tab.h" %} %% a {return A;} b {return B;} . {return yytext[0];} \n {return yytext[0];} %%

Yacc program

%token A B %% str : s'\n' {return 0;} s : A s B ; | ; %% int main() { printf("Type the string\n"); yyparse(); printf("Valid string"); } int yyerror() { printf("Invalid string"); exit(0); }

OUTPUT [root@localhost ~]# lex pgm5b.l [root@localhost ~]# yacc -d pgm5b.y [root@localhost ~]# cc lex.yy.c y.tab.c -ll [root@localhost ~]# ./a.out Type the string aaabbb Valid string Type the string aaab Invalid string

Page 18: System Software Lab VI Sem ISE

System Software Laboratory Manual

Dept. Of I. S. E.

18

K.L.E.I.T-HUBLI

6. Program to recognize the grammar (anb, n>= 10).

Lex program

%{ #include "y.tab.h" int count = 0; %} %% [a] {count++; return A;} [b] { if (count >= 10) return B; else return error; } \n {return 0;} . {return error;} %%

Yacc program

%{ #include<stdio.h> int flag = 1; %} %token A B err; %% expn:A inexp B |error {yyerror("");} ; inexp: A inexp |error {yyerror("");} | ; %% main() { yyparse(); if (flag) printf("Valid"); } yyerror(char *s) { printf("Invalid"); exit(0); flag = 0; }

Page 19: System Software Lab VI Sem ISE

System Software Laboratory Manual

Dept. Of I. S. E.

19

K.L.E.I.T-HUBLI

OUTPUT [root@localhost ~]# lex pgm6.l [root@localhost ~]# yacc -d pgm6.y [root@localhost ~]# cc lex.yy.c y.tab.c -ll [root@localhost ~]# ./a.out Type the string aaaaaaaaaaab Valid string Type the string aabb Invalid string

Page 20: System Software Lab VI Sem ISE

System Software Laboratory Manual

Dept. Of I. S. E.

20

K.L.E.I.T-HUBLI

PART B

UNIX Programming

INTRODUCTION TO SHELL PROGRAMMING

A set of commands that are taken together as a single unit within a file and executed at a stretch is called a shell program or a shell script.

A shell script is named just like all other files. However, by convention shell script name uses .sh extension. A shell program runs in the interpretive mode ,that is ,one statement is executed at a time.

Example :

#!/bin/sh echo “Today’s date is :`date` “ #to display the date echo “My shell :$SHELL”

example.sh

The first line is interpreter line. Here, this line specifies the shell we are using i.e Bourne shell. A shell script is executed by using the shell command sh as shown below.

[root@localhost ~]# sh example.sh or else use [root@localhost ~]# . /example.sh

Today’s date is : Sat Jan 27 09:10:18 IST 2004 My Shell :/bin/sh Comments

In shell scripts comments are written using the hash (#) character as the first character of the comment line.

The read Command

The read command or statement is the shell’s internal tool for taking the input from the user, i.e., making scripts interactive. It is used with one or more variables. Input supplied through the standard input is read into the variables. #!/bin/sh

echo “Enter the value of x” read x

echo “The value of x is : $x”

value.sh

When you use a statement like read x the script pauses at that point to take input

Page 21: System Software Lab VI Sem ISE

System Software Laboratory Manual

Dept. Of I. S. E.

21

K.L.E.I.T-HUBLI

from the keyboard. Whatever you enter is stored in the variable x.. Since this is a form of assignment, no $ is used before x. To display that value we have to use $ symbol along with variable.

Special parameters Used by Shell

Using command line

command.sh

[root@localhost ~]# sh command.sh Nokia Motorola #command line The program Name: command.sh

The number of arguments specified is: 2 The arguments are: Nokia Motorola

Value of Nokia and Motorola The first argument is read by the shell into the parameter $1, the second argument into $2.We can use more positional parameters in this way up to $9. (And using the shift command, you can go beyond)

The if Conditional

This is the simplest of all the branching control structures. It has the following general formats. Every if is close with corresponding fi ,and you’ll encounter an error of one is not present.

Page 22: System Software Lab VI Sem ISE

System Software Laboratory Manual

Dept. Of I. S. E.

22

K.L.E.I.T-HUBLI

If command succeeds ,the sequence of commands following it is executed .If command fails, then the else statement(if present) is executed.

Using test and [ ] to evaluate expressions

When you use if to evaluate expressions, you need the test statement because the true or false values returned by expressions can’t be directly handled by if. test Uses certain operators to evaluate the condition and either a true or false exit status, which is then used by if for making decisions. Numerical comparison operators used by test.

The operators begins with . (hyphen) ,followed by a two-letter string. The operators are quite mnemonic; -eq implies equal to ,-lt less than and so on.

Example: [root@localhost ~]# a=8 ; b=9 ; to combine the commands [root@localhost ~]# test $a .eq $b ; echo $? [root@localhost ~]# 1 False

[root@localhost ~]# test $a .lt $b [root@localhost ~]# 0 True

expr :Computation

expr can perform basic arithmetic operations (+,-,*,/,%). [root@localhost ~]# a=2 ; b=9 [root@localhost ~]# c= ‘expr $x + $y ‘ ; echo .$c. [root@localhost ~]# 11 The operands must be enclosed on either side by whitespace. For multiplication we have to use \ (Escaping technique) to prevent the shell from interpreting it as metacharacter.

Page 23: System Software Lab VI Sem ISE

System Software Laboratory Manual

Dept. Of I. S. E.

23

K.L.E.I.T-HUBLI

while Looping while statement repeatedly performs a set of instructions until the control command returns a true exit status. The general syntax of this: while condition is true do # do is a keyword commands

done #done is a keyword The commands enclosed by do and done are executed repeatedly as long as condition remains true.

The case conditional In case statement, the statement which matches an expression is executed. The general syntax of the case statement is as follows: case expression in

pattern1)command1;; pattern2)command2;; pattern3)command2;; ....

esac

case first matches expression with pattern1.If match succeeds, the it.s executes command1.If matches fails, the pattern2 is matched ,and so forth. Each command list is terminated with a pair of semicolons, and the entire construct is closed with esac (reverse of case).

eval command

The use of eval command makes the shell to scan the command line once more, that is, second time and then actually executes the command line. Example: [root@localhost ~]# b=a [root@localhost ~]# c=b [root@localhost ~]# eval echo \$$c [root@localhost ~]# a The first two statements in this example are assignment statement. When the shell comes cross the third statement, because of eval; it first scans the statements once for any possible pre-evaluation or substitution. Here because of metacharacter \ the first $ is overlooked and the next variable $c gets evaluated resulting b. After this evaluation the third statement will be equivalent to echo $b. Then this statement gets executed as usual by the shell resulting as the answer.

Page 24: System Software Lab VI Sem ISE

System Software Laboratory Manual

Dept. Of I. S. E.

24

K.L.E.I.T-HUBLI

1a. Non-recursive shell script that accepts any number of arguments and prints

them in the reverse order, ( For example, if the script is named rargs then

executing rargs A B C should produce C B A on the standard output). #!/bin/sh c=$# echo "The arguments in reverse order are:" while [ $c -ne 0 ] do eval echo \$$c c=`expr $c - 1` done

OUTPUT [root@localhost ~]# sh 1a.sh e c t The arguments in reverse order are: t c e

1b. C program that creates a child process to read commands from the standard

input and execute them (a minimal implementation of a shell . like program).

You can assume that no arguments will be passed to the commands to be

executed. #include<stdio.h> #include<stdlib.h> #include<unistd.h> main() { int x,i; char cmd[10]; x=fork (); /*To create a child process*/ if(x==0) do { printf("Child process has been created\n"); printf("Enter the command to be executed\n"); scanf("%s",cmd); system(cmd); printf("Enter 1 to continue and 0 to exit\n"); scanf("%d",&i); } while(i!=0); wait(); }

OUTPUT [root@localhost ~]# cc filename.c [root@localhost ~]# ./a.out Child process has been created Enter the command to be executed date Tue Jan 19 16:17:01 IST 2010 Enter 1 to continue and 0 to exit 1

Page 25: System Software Lab VI Sem ISE

System Software Laboratory Manual

Dept. Of I. S. E.

25

K.L.E.I.T-HUBLI

2a. Shell script that accepts two file names as arguments, checks if the

permissions for these files are identical and if the permissions are identical,

outputs the common permissions, otherwise outputs each file name followed

by its permissions. #!/bin/sh perm1=`ls -l $1|cut -c 1-10` perm2=`ls -l $2|cut -c 1-10` if [ $perm1 = $perm2 ] then echo "Files have same permissions" echo "The Files permission is $perm1" else echo "The Files have different permission " echo "$1 has permission $perm1" echo "$2 has permission $perm2" fi

OUTPUT

Run1

nandeesh@Galaxy:~$ sh 2a.sh a.txt b.txt Files have same permissions The Files permission is -rw-r--r-- nandeesh@Galaxy:~$ chmod 777 b.txt

Run2 nandeesh@Galaxy:~$ sh 2a.sh a.txt b.txt The Files have different permission a.txt has permission -rw-r--r-- b.txt has permission -rwxrwxrwx

2b. C program to create a file with 16 bytes of arbitrary data from the beginning

and another 16 bytes of arbitrary data from an offset of 48. Display the file

contents to demonstrate how the hole in file is handled. #include<stdio.h> #include<sys/types.h> int main() { char buf1[]="abcdefghijklmnop"; char buf2[]="ABCDEFGHIJKLMNOP"; int fd=creat("data.txt","w"); /*creating a file*/ write(fd,buf1,16); /*writing the data*/ lseek(fd,48,SEEK_SET); /*To set the offset*/ write(fd,buf2,16); system("vi data.txt"); return 0; }

OUTPUT [root@localhost ~]# cc 2b.c [root@localhost ~]# ./a.out abcdefghijklmnop^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@ ^@^@^@^@^@^@^@^@^@^@^@^@^@ABCDEFGHIJKLMNOP

Page 26: System Software Lab VI Sem ISE

System Software Laboratory Manual

Dept. Of I. S. E.

26

K.L.E.I.T-HUBLI

3a.Shell function that takes a valid directory names as an argument and

recursively descends all the subdirectories, finds the maximum length of any

file in that hierarchy and writes this maximum value to the standard output.

#/bin/sh echo "Enter the directory name" read dirname ls -lR $dirname|cut -c 31-34,52-68|sort -n>f2 cat f2 echo "Maximum size file is:" tail -1 f2

OUTPUT nandeesh@Galaxy:~$ sh 3a.sh Enter the directory name ls 25 t.txt 171 4b.l 441 1a.yacc 528 4b.y Maximum size file is: 528 4b.y

3b. C program that accepts valid file names as command line arguments and for

each of the arguments, prints the type of the file ( Regular file, Directory file,

Character special file, Block special file, Symbolic link etc.)

#include<stdio.h> #include<sys/stat.h> #include<sys/types.h> #include<unistd.h> int main(int argc,char *argv[]) {

int i; struct stat buf; for(i=1;i<argc;i++) { lstat(argv[i],&buf); printf("%s\n",argv[i]); if(S_ISCHR(buf.st_mode)) printf("File is a character file\n"); else if(S_ISBLK(buf.st_mode)) printf("File is a block file\n"); else if(S_ISREG(buf.st_mode)) printf("File is regular file\n"); else if(S_ISDIR(buf.st_mode)) printf("File is a directory file\n");

Page 27: System Software Lab VI Sem ISE

System Software Laboratory Manual

Dept. Of I. S. E.

27

K.L.E.I.T-HUBLI

else if(S_ISLNK(buf.st_mode)) printf("Symbolic link file\n");

} return(0);

}

OUTPUT

[root@localhost ~]# cc 3b.c [root@localhost ~]# ./a.out x.c data1 data2 data3 x.c File is regular file data1 File is a block file data2 File is a character file data3 Symbolic link file

Page 28: System Software Lab VI Sem ISE

System Software Laboratory Manual

Dept. Of I. S. E.

28

K.L.E.I.T-HUBLI

4a. Shell script that accepts file names specified as arguments and creates a shell

script that contains this file as well as the code to recreate these files. Thus if

the script generated by your script is executed, it would recreate the original

files.

#! /bin/bash echo "#to unbundled ,bash this file" for i do echo "echo $i 1>&2" echo "cat >$i << 'End of $i'" cat $i echo "End of $i" done

OUTPUT

[root@localhost ~]# vi data1.txt [root@localhost ~]# vi data2.txt Redirect the contents of files to another file [root@localhost ~]# sh filename.sh data1.txt data2.txt > data3.txt See the Content of the file using cat command. [root@localhost ~]# cat data3.txt #to unbundled ,bash this file echo data1.txt 1>&2 cat >data1.txt << 'End of data1.txt' Unix /*Content of data1.txt*/ End of data1.txt echo data2.txt 1>&2 cat >data2.txt << 'End of data2.txt' shell programming /*Content of data2.txt*/ End of data2.txt

Page 29: System Software Lab VI Sem ISE

System Software Laboratory Manual

Dept. Of I. S. E.

29

K.L.E.I.T-HUBLI

4b.C program to do the following: Using fork ( ) create a child process. The child

process prints its own process-id and id of its parent and then exits. The

parent process waits for its child to finish (by executing the wait ( )) and prints

its own process-id and the id of its child process and then exits.

#include<stdio.h> #include<sys/types.h> #include<unistd.h> int main() { int status; int pid,ppid,mpid; pid=fork(); if(pid<0) { printf("Error in forking child"); } if(pid==0) { ppid=getppid(); printf("I am the child and my parent id %d\n",ppid); mpid=getpid(); printf("Child process\n"); printf("My own id is %d\n",mpid); } wait(); mpid=getpid(); printf("My id is %d and my child id is %d\n",mpid,pid); }

OUTPUT nandeesh@Galaxy:~$ cc 4b.c nandeesh@Galaxy:~$ ./a.out I am the child and my parent id 4220 Child process My own id is 4221 My id is 4221 and my child id is 0 My id is 4220 and my child id is 4221

Page 30: System Software Lab VI Sem ISE

System Software Laboratory Manual

Dept. Of I. S. E.

30

K.L.E.I.T-HUBLI

5a.Write a shell script that accepts path names and creates all the components in

that path names as directories. For example, if the script is mpe, then the

command mpe a/b/c/d should create directories a, a/b, a/b/c and a/b/c/d.

#!/bin/sh echo "recurssively creating the dir" mkdir -pv $1

OUTPUT nandeesh@Galaxy:~$ sh 5a.sh a/b/c/d recurssively creating the dir

5b.Write a C program that accepts one command-line argument, executes the

arguments as shell command, determines the time taken by it and prints the

time values, Use the “times”, function and the “tms” structure. The code need

not include error checking.

#include<stdlib.h> #include<stdio.h> #include<sys/types.h> #include<sys/times.h> #include<unistd.h> int main(int argc, char *argv[]) { int i; struct tms t1,t2; clock_t strt,finish; double clcktck=sysconf(_SC_CLK_TCK); strt=times(&t1); for(i=1;i<argc;i++) system(argv[i]); finish=times(&t2); printf("\nRealTime taken=%f",(finish-strt)/clcktck); }

OUTPUT nandeesh@Galaxy:~$ ./a.out ps PID TTY TIME CMD 4193 pts/0 00:00:00 bash 4258 pts/0 00:00:00 a.out 4259 pts/0 00:00:00 sh 4260 pts/0 00:00:00 ps RealTime taken=0.020000

Page 31: System Software Lab VI Sem ISE

System Software Laboratory Manual

Dept. Of I. S. E.

31

K.L.E.I.T-HUBLI

6a. Shell script that accepts valid log-in names as arguments and prints their

corresponding home directories. If no arguments are specified, print a

suitable error message.

#!#!/bin/sh w=$# if [ $w -eq 0 ] then echo "No arguments supplied" exit else for logname in $* do grep $logname /etc/passwd>file if [ $? -ne 0 ]; then echo "Invalid login name" exit else echo "Valid login name" cut -d ":" -f6 file fi done fi

OUTPUT nandeesh@Galaxy:~$ sh 6aa.sh No arguments supplied nandeesh@Galaxy:~$ sh 6aa.sh nandeesh Valid login name /home/nandeesh nandeesh@Galaxy:~$ sh 6aa.sh nagaraj Invalid login name

Page 32: System Software Lab VI Sem ISE

System Software Laboratory Manual

Dept. Of I. S. E.

32

K.L.E.I.T-HUBLI

6b. C program that accepts a valid directory names as a command line argument

and lists all the files in the given directory as well as all the subsequent

subdirectories. (The solution can be recursive or non-recursive).

#include<unistd.h>

#include<dirent.h>

#include<stdio.h>

#include<stdlib.h>

int main(int argc, char *argv[])

{

DIR *dp;

struct dirent *dirp;

if(argc!=2)

{

printf("Don't have sufficient arguments\n");

exit(0);

}

if((dp=opendir(argv[1]))==NULL)

{

printf("Directory cann't be open\n");

exit(0);

}

printf("contents of the directory are\n");

while((dirp=readdir(dp))!=NULL)

printf("%s\n",dirp->d_name);

closedir(dp);

return(0);

}

/*OUTPUT

nandeesh@nandeesh-laptop:~$ cc 6b.c

nandeesh@nandeesh-laptop:~$ ./a.out Documents

contents of the directory are

Work Load 2009 10.doc

result analysis.doc

LAB AREA.doc */

Page 33: System Software Lab VI Sem ISE

System Software Laboratory Manual

Dept. Of I. S. E.

33

K.L.E.I.T-HUBLI

7. a) Shell script to implement terminal locking. It should prompt the user for a

password. After accepting the password entered by the user, it must prompt

again for password confirmation (to retype the password). If a match occurs,

it must lock the terminal and promp for the password. If the proper password

is entered, the terminal must be unlocked. Note the script must be written to

disregard BREAK, Control-D etc. No time limit need be implemented for the

lock duration.

stty -echo echo “Enter the password: ” read pw echo “Confirm password: ” read cpw echo "$pw" echo "$cpw" if [ "$pw" = "$cpw" ] then echo “Keyboard locked” trap “.” 1 2 15 18 30 else echo "Incorrect password" exit fi echo “Enter password to resume read npw if [ "$pw" = "$npw" ]; then echo “Enter password” echo “Terminal unlock” else echo "Incorrect password" exit fi

stty sane

OUTPUT

RUN1 RUN2

nandeesh@Galaxy:~$ sh 7aa.sh nandeesh@Galaxy:~$ sh 7aa.sh “Enter the password: ” “Enter the password: ” “Confirm password: ” “Confirm password: ” “Keyboard locked” “Keyboard locked” “Enter password to resume “Enter password to resume “Enter password” Incorrect password “Terminal unlock” nandeesh@Galaxy:~$

Page 34: System Software Lab VI Sem ISE

System Software Laboratory Manual

Dept. Of I. S. E.

34

K.L.E.I.T-HUBLI

7b) C program to prompt the user for the name of an environment variable and

print its value if it is defined and a suitable message otherwise; and to repeat

the process if user wants it.

#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<string.h> int main() { char env[10],*p; int ch=1; while(ch!=0) { printf(“\n Enter name of evironment variable :”); scanf(“%s”,env); p=getenv(env); printf(“%s”,p); printf(“\n Want to change ? 1 for yes & 0 for no :”); scanf(“%d”,&ch); } return 0; }

OUTPUT nandeesh@Galaxy:~$ cc p1.c nandeesh@Galaxy:~$ ./a.out Enter the environmental variable name:PATH value=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games Do you want to continue? press 0 to exit 1 to continue:1 Enter the environmental variable name:SHELL value=/bin/bash Do you want to continue? press 0 to exit 1 to continue:0