Вы находитесь на странице: 1из 34

System Software Laboratory Manual 1

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.

Dept. Of I. S. E. K.L.E.I.T-HUBLI
System Software Laboratory Manual 2

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.

Dept. Of I. S. E. K.L.E.I.T-HUBLI
System Software Laboratory Manual 3

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.

Dept. Of I. S. E. K.L.E.I.T-HUBLI
System Software Laboratory Manual 4

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

Dept. Of I. S. E. K.L.E.I.T-HUBLI
System Software Laboratory Manual 5

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.

Dept. Of I. S. E. K.L.E.I.T-HUBLI
System Software Laboratory Manual 6

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

Dept. Of I. S. E. K.L.E.I.T-HUBLI
System Software Laboratory Manual 7

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

Dept. Of I. S. E. K.L.E.I.T-HUBLI
System Software Laboratory Manual 8

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

Dept. Of I. S. E. K.L.E.I.T-HUBLI
System Software Laboratory Manual 9

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

Dept. Of I. S. E. K.L.E.I.T-HUBLI
System Software Laboratory Manual 10

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

Dept. Of I. S. E. K.L.E.I.T-HUBLI
System Software Laboratory Manual 11

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.

Dept. Of I. S. E. K.L.E.I.T-HUBLI
System Software Laboratory Manual 12

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

Dept. Of I. S. E. K.L.E.I.T-HUBLI
System Software Laboratory Manual 13

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.

Dept. Of I. S. E. K.L.E.I.T-HUBLI
System Software Laboratory Manual 14

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

Dept. Of I. S. E. K.L.E.I.T-HUBLI
System Software Laboratory Manual 15

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()
{

Dept. Of I. S. E. K.L.E.I.T-HUBLI
System Software Laboratory Manual 16

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

Dept. Of I. S. E. K.L.E.I.T-HUBLI
System Software Laboratory Manual 17

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:AsB;
|;
%%
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

Dept. Of I. S. E. K.L.E.I.T-HUBLI
System Software Laboratory Manual 18

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;
}

Dept. Of I. S. E. K.L.E.I.T-HUBLI
System Software Laboratory Manual 19

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

Dept. Of I. S. E. K.L.E.I.T-HUBLI
System Software Laboratory Manual 20

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

Dept. Of I. S. E. K.L.E.I.T-HUBLI
System Software Laboratory Manual 21

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.

Dept. Of I. S. E. K.L.E.I.T-HUBLI
System Software Laboratory Manual 22

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.

Dept. Of I. S. E. K.L.E.I.T-HUBLI
System Software Laboratory Manual 23

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.

Dept. Of I. S. E. K.L.E.I.T-HUBLI
System Software Laboratory Manual 24

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:
tce

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

Dept. Of I. S. E. K.L.E.I.T-HUBLI
System Software Laboratory Manual 25

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

Dept. Of I. S. E. K.L.E.I.T-HUBLI
System Software Laboratory Manual 26

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");

Dept. Of I. S. E. K.L.E.I.T-HUBLI
System Software Laboratory Manual 27

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

Dept. Of I. S. E. K.L.E.I.T-HUBLI
System Software Laboratory Manual 28

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

Dept. Of I. S. E. K.L.E.I.T-HUBLI
System Software Laboratory Manual 29

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

Dept. Of I. S. E. K.L.E.I.T-HUBLI
System Software Laboratory Manual 30

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

Dept. Of I. S. E. K.L.E.I.T-HUBLI
System Software Laboratory Manual 31

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

Dept. Of I. S. E. K.L.E.I.T-HUBLI
System Software Laboratory Manual 32

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 */

Dept. Of I. S. E. K.L.E.I.T-HUBLI
System Software Laboratory Manual 33

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:~$

Dept. Of I. S. E. K.L.E.I.T-HUBLI
System Software Laboratory Manual 34

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

Dept. Of I. S. E. K.L.E.I.T-HUBLI

Вам также может понравиться