Compiler Deign Lab Programs
1.a)Non-recursive shell script that accepts any number of arguments and prints them in the reverse order.
Filename : 1a.sh
echo "number of arguments are : $#"
len=$#
while [ $len -ne 0 ]
do
eval echo \$$len
len=`expr $len - 1`
done
output :
$ chmod 777 1a.sh
$ ./1a.sh 1 2 3
number of arguments are : 3
3
2
1
$ ./1a.sh dilip mithun pavan
number of arguments are : 3
pavan
mithun
dilip
1.b)C program that creates a child process to read commands from the standard input and execute them ( a minimal implementation pf a shell – like a program). You can assume that no arguments will be passed to the commands to be executed.
Filename : 1b.c
#include
#include
int main()
{
char cmd[20];
pid_t pid;
int ch;
pid=fork();
if(pid == 0)
{
do
{
printf("\n Enter the command to be executed : ");
scanf("%s",cmd);
system(cmd);
printf("\n Enter 1 to continue and 0 to exit : ");
scanf("%d",&ch);
}
while(ch!=0);
}
wait();
}
output :
$ cc 1b.c
$ ./a.out
Enter the command to be executed : date
Tue Mar 1 22:05:52 IST 2005
Enter 1 to continue and 0 to exit : 1
Enter the command to be executed : cal
March 2005
Su Mo Tu We Th Fr Sa
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
Enter 1 to continue and 0 to exit : 0
Note : The program 1b can also written as given below in an more appropriate form
Filename : 1b.c
#include
#include
#include
#include
#include
#include
#define MAXLINE 10
int main()
{
char buf[MAXLINE];
pid_t pid;
int status;
system("tput clear");
printf("Type any command(without options):\n");
printf("#");
fgets(buf,MAXLINE,stdin);
buf[strlen(buf)-1]=0;
while(strlen(buf)!=0)
{
if((pid=fork())<0)
{
printf("fork error");
}
else if(pid==0)
{
execlp(buf,buf,(char *) 0);
printf("couldn't execute : %s\n",buf);
exit(0);
}
if((pid=waitpid(pid,&status,0))<0)
printf("waitpid error");
printf("#");
fgets(buf,MAXLINE,stdin);
buf[strlen(buf)-1]=0;
}
exit(0);
}
output :
$ cc 1b.c
$ ./a.out
# date
Tue Mar 1 22:05:52 IST 2005
2.a)Shell script that accepts two file names as arguments, checks if the permissions of these files are identical and if the permissions are identical, outputs the common permission, otherwise outputs each file name followed by its permission.
Filename : 2a.sh
ls -l $1 | cut -d " " -f 1 > file1per
ls -l $2 | cut -d " " -f 1 > file2per
if cmp file1per file2per
then
echo "Both the files have same permission"
cat file1per
else
echo "Both the files have different permission"
echo "The permission of first file $1 is "
cat file1per
echo "The permission of second file $2 is "
cat file2per
fi
output :
$chmod 777 2a.sh
$cat > file1
this is first file content
$cat > file2
this is second file content
$./2a.sh file1 file2
Both the files have same permission
-rw-r--r--
$chmod 777 file2
$./2a.sh file1 file2
file1per file2per differ: byte 4, line 1
Both the files have different permission
The permission of first file file1 is
-rw-r--r--
The permission of second file file2 is
-rwxrwxrwx
2.b)C program to create a file with 16 bytes of arbitary data from the beginning and another 16 bytes of arbitary data from an offset of 48. Display the file contents to demonstrate how the hole in file is handled
Filename : 2b.c
#include
#include
#include
#include
int main()
{
int fd;
char buf1[]="Department of IS";
char buf2[]="Department of CS";
fd=creat("ise",0622);
if(fd <>
{
printf("\n Error in creating file");
exit(0);
}
write(fd,buf1,16);
lseek(fd,48,SEEK_SET);
write(fd,buf2,16);
exit(0);
}
output :
$cc 2b.c
$./a.out
$od -c ise
0000000 D e p a r t m e n t o f I S
0000020 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
*
0000060 D e p a r t m e n t o f C S
0000100
3.a)Shell script that takes a valid directory names as as argument and recursively descends all the subdirectories, finds the maximum length of any file in that hierarchy and writes this maximum valut to the standard output.
Filename : 3a.sh
maxsize=`ls -lR $1 | grep '^-' | cut -c 35-42 | sort -n | tail -1`
echo "The max size of the file in directort $1 is $maxsize bytes"
output :
$chmod 777 3a.sh
$ls -l
total 12
-rwxr-xr-x 1 root root 148 Mar 1 22:17 1a.sh
-rwxr-xr-x 1 root root 366 Mar 1 22:17 2a.sh
-rwxrwxrwx 1 root root 192 Mar 1 22:17 3a.sh
$./3a.sh /root/6ise/unix
The max size of the file in directort /root/6ise/unix is 366 bytes
3.b)C program that accepts valid file names as coomand 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 .. )
Filename : 3b.c
#include
#include
#include
#include
int main(int argc, char *argv[])
{
int i;
struct stat buf;
for(i=1; i<>
{
printf("%s: ", argv[i]);
lstat(argv[i],&buf);
if(S_ISREG(buf.st_mode))
printf("file is a regular file\n");
if(S_ISDIR(buf.st_mode))
printf("file is a directory file\n");
if(S_ISCHR(buf.st_mode))
printf("file is a character file\n");
if(S_ISBLK(buf.st_mode))
printf("file is a block file\n");
if(S_ISLNK(buf.st_mode))
printf("file is a symbolic link file\n");
}
exit(0);
}
output :
$cc 3b.c
$./a.out /root/6ise/3b.c
/root/6ise/3b.c: file is a regular file
$./a.out /root/6ise/3b.c /root/6ise
/root/6ise/3b.c: file is a regular file
/root/6ise: file is a directory file
$./a.out /dev/tty
/dev/tty: file is a character file
4.a)Shell script that accepts pathnames and creates all the components in that path names as directories. For example, if the script name in mpe, then the command mpe a/b/c/d should create directories a,a/b,a/b/c and a/b/c/d.
Filename : 4a.sh
if [ $# -le 0 -o $# -gt 1 ]
then
echo "Improper Usage pathname required"
else
mkdir -p $1
fi
output :
$chmod 777 4a.sh
$./4a.sh a/b/c/d
$cd a
$ls
b
$cd b
$ls
c
$cd c
$ls
d
4.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.
Filename : 4b.c
#include
#include
#include
int main(int argc, char *argv[])
{
struct tms tms1,tms2;
clock_t start,end;
long clktck = sysconf(_SC_CLK_TCK);
start=times(&tms1);
system(argv[1]);
end=times(&tms2);
printf("\n The total execution(wall clock) time is %3.2f\n",(end- start) / (double) clktck);
printf("\n The User cpu time is %3.2f\n",(tms2.tms_utime - tms1.tms_utime) / (double) clktck);
printf("\n The System cpu time is %3.2f\n",(tms2.tms_stime - tms1.tms_stime) / (double) clktck);
printf("\n The User cpu time of the terminated child process is %3.2f\n",(tms2.tms_cutime - tms1.tms_cutime) / (double) clktck);
printf("\n The System cpu time of the terminated child process is %3.2f\n",(tms2.tms_cstime - tms1.tms_cstime) / (double) clktck);
exit(0);
}
output :
$cc 4b.c
$./a.out ls
10a.awk 1b1 2b 3b.c 5a.sh 5b.c 7b.awk 9b.pl file1per
10b 1b1.c 2b.c 4a.sh 5b 6a.sh 8a.sh a file2
10b.c 1b.c 3a.sh 4b 5b1 6b.c 8b.pl a.out file2per 2a.sh 3b 4b.c 5b1.c 7a.sh 9a.sh
The total execution(wall clock) time is 0.01
The User cpu time is 0.00
The System cpu time is 0.00
The User cpu time of the terminated child process is 0.00
The System cpu time of the terminated child process is 0.01
5.a)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.
Filename :5a.sh
if [ $# -lt 1 ]
then
echo "Improper Usage :$0 No Login Name"
fi
for i
do
awk -F: '{print $1,$6}' /etc/passwd | grep -i ^"$i"
done
output :
$chmod 777 5a.sh
$./5a.sh
Improper Usage :./5a.sh No Login Name
$./5a.sh girish
girish /home/girish
$./5a.sh root
root /root
5.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 suddirectories.
Filename : 5b.c
#include
#include
int main(int argc, char *argv[])
{
int i;
char str[50];
for(i=1;i
{
strcpy(str," ls -R ");
strcat(str,argv[i]);
system(str);
}
}
output :
$cc 5b1.c
$./a.out /root/6ise
/root/6ise:
10a.awk 1b1 2b 3b.c 5a.sh 5b.c 7b.awk 9b.pl file1per
10b 1b1.c 2b.c 4a.sh 5b 6a.sh 8a.sh a file2
10b.c 1b.c 3a.sh 4b 5b1 6b.c 8b.pl a.out file2per
1a.sh 2a.sh 3b 4b.c 5b1.c 7a.sh 9a.sh file1 in10
/root/6ise/a:
b
/root/6ise/a/b:
c
/root/6ise/a/b/c:
d
/root/6ise/a/b/c/d:
/root/6ise/unix:
1a.sh 2a.sh 3a.sh
6.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 passwprd). 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.
Filename :6a.sh
trap "" 1 2 3
stty -echo
echo "Enter your password:"
read key1
echo "Retype your password:"
read key2
if [ $key1 = $key2 ]
then
clear
key3=""
until [ "$key3" = "$key2" ]
do
read key3
done
else
echo "Wrong password . you are a illegal user"
fi
stty echo
output :
$./6a.sh
Enter your password :
Retype your password :
NOTE : Now the terminal gets locked and to invoke the terminal you have to re-type the password.
$
6.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.
Filename : 6b.c
#include
#include
#include
#include
#include
int main(void)
{
char name[25];
int i=1;
char *p;
do
{
printf("\n Enter any Environment variable :");
scanf("%s",name);
p=getenv(name);
if(p)
printf("%s",p);
else
printf("\n Environment variable donot match");
printf("\n Want to continue 1--yes 0-no :\n");
scanf("%d",&i);
}
while(i!=0);
}
output :
$cc 6b.c
$./a.out
Enter any Environment variable :HOME
/root
Want to continue 1--yes 0-no :
1
Enter any Environment variable :PATH
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin:/root/bin
Want to continue 1--yes 0-no :
0
7.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.
Filename : 7a.sh
echo '#to bundle,sh this file'
for i in $*
do
echo "echo $i 1>&2"
echo "cat >$i <<'End of $i'"
cat $i
echo "End of $i"
done
output:
$chmod 777 7a.sh
$ls
10b.c 1b.c 4a.sh 5a.sh 5b.c 6a.sh 6b.c 7a.sh 8a.sh 9a.sh a
$cat > file1
this is first file
$cat > file2
this is second file
$ls
10b.c 4a.sh 5b.c 6b.c 8a.sh a file2
1b.c 5a.sh 6a.sh 7a.sh 9a.sh file1
$./7a.sh file1 file2 > new.sh
$ls
10b.c 4a.sh 5b.c 6b.c 8a.sh a file2
1b.c 5a.sh 6a.sh 7a.sh 9a.sh file1 new.sh
$rm file1
rm: remove regular file `file1'? y
$rm file2
rm: remove regular file `file2'? y
$ls
10b.c 1b.c 4a.sh 5a.sh 5b.c 6a.sh 6b.c 7a.sh 8a.sh 9a.sh a new.sh
$chmod 777 new.sh
$./new.sh
file1
file2
$ls
10b.c 4a.sh 5b.c 6b.c 8a.sh a file2
1b.c 5a.sh 6a.sh 7a.sh 9a.sh file1 new.sh
$cat file1
this is first file
$cat file2
this is second file
7.b)Awk script to delete duplicated lines from a text file. The order of the original must remain unchanged.
Filename : 7b.awk
{
found=0
for(i=0;i
if(lines[i] == $0)
{
found=1
break
}
if(!found)
{
lines[nlines++]=$0
print $0
}
}
ouput :
$cat > input
ise
ise
vit
cse
cse
bangalore
$awk -f 7b.awk input
ise
vit
cse
bangalore
$cat input
ise
ise
vit
cse
cse
bangalore
8.a)Shell script to find and display all the links of a file specified as the first argument to the script. The second argument is optional,can be used to specify the directory in which the search is to begin. If this second argument is not present, the search is to begin in current working directory. In either case, the starting directory as well as its subdirectories al all levels must be searched. The script need not include any error checking.
Filename : 8a.sh
file="$1"
if [ $# -eq 1 ]
then
directory="."
else
directory="$2"
fi
set -- $( ls -l "$file" )
linkcnt=$2
if [ "$linkcnt" = 1 ]
then
echo "no other links to $file" 1>&2
exit 0
fi
set -- $( ls -i "$file" )
inode=$1
find "$directory" -xdev -inum $inode -print
output :
$chmod 777 8a.sh
$cat > input
this is a simple text file.
$./8a.sh input
no other links to input
$ln input ouput
$./8a.sh input
./input
./ouput
8.b)PERL script that echoes its command line arguments,one per line after translating all lower case letters to upper case.
Filename : 8b.pl
foreach $string (@ARGV)
{
$string=~tr/a-z/A-Z/;
print("$string\n");
}
ouput :
$perl 8b.pl welcome to unix lab
WELCOME
TO
UNIX
LAB
9.a)Shell script to display the calendar for current month with current date replaced by * and ** depending on whether date has one digit or two digit.
Filename : 9a.sh
cal >daymo
set `date`
y=`expr $3 : '.*'`
if [ $y -eq 1 ]
then
sed "s/ $3/ \*/" daymo
else
sed "s/ $3/ \**/" daymo
fi
rm daymo
output :
$chmod 777 9a.sh
$./9a.sh
March 2005
Su Mo Tu We Th Fr Sa
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 ** 19
20 21 22 23 24 25 26
27 28 29 30 31
9.b)PERL program to convert an unsigned binary number(supplied as arg) to decimal(for example if the arg is 10110 the output should be 22). If an argument is present,it can be a valid binary number and if no argument is present, the program should display an error message.
Filename : 9b.pl
if(@ARGV==0)
{
print("INVALID argument\n");
}
else
{
$num=0;
$mul=1;
while($ARGV[0] != " ")
{
$num = $num + chop($ARGV[0]) * $mul;
$mul = $mul * 2;
}
print("$num\n");
}
output :
$perl 9b.pl 101
5
$perl 9b.pl 1010
10
10.a)Awk script that folds long line into 40 columns. Thus any line that exceeds 40 characters must be broken after 40th and is to be continued with the residue. The inputs to be supplied through a text file created by the user.
Filename : 10a.awk
{
x=$0
while(length(x) > 40)
{
printf("%sX\n",substr(x,1,40))
x=substr(x,41,length(x)-40)
}
printf("%s\n",x)
}
ouput :
$cat > xyz.txt
this is a text file that is supplied as an input to the 10th program
unix is really a nice and interesting subject
$awk -f 10a.awk xyz.txt
this is a text file that is supplied as
an input to the 10th program
unix is really a nice and interesting su
bject
10.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 wait( )) and prints its own process-id and the id of its child process and then exits.
Filename : 10b.c
#include
#include
int main()
{
pid_t pid;
if((pid=fork())<0)
printf("fork error");
if(pid==0)
{
printf("\n This is child process ");
printf("\n Child PID :%d",getpid());
printf("\n Parent PID :%d\n",getppid());
exit(0);
}
else
{
wait();
printf("\n This is parent process");
printf("\n Parent PID :%d",getpid());
printf("\n Child PID :%d",pid);
exit(0);
}
}
output :
$cc 10b.c
$./a.out
This is child process
Child PID :3122
Parent PID :3121
This is parent process
Parent PID :3121
Child PID :3122
Acknowledgement: Compiled by Prof. Girish Rao Salanke