6/17/08

C Program to execute shell script

As I promised in my previous post Suse Linux View CPU speed and Hard disk/CPU temperature I am back to publish my little C program which executes the script. Actually I extended it a little so it can execute any script witch is given as argument and it is located in the same directory with the executable (after compiling the code below).

Well,
The first think needed was how to execute a script.
I first though was fork() and execv().
But after a while I remember that I could use the command system() with argument the script path.

The second think I needed to know was the directory path of execution.
This isn't that difficult, you can have the directory path with the command getenv("PWD");

Here is the first version of my little program witch executes only the script in Suse Linux View CPU speed and Hard disk/CPU temperature post.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXPATH 127
int main(int argc,char* argv[]){
char *path = malloc(MAXPATH);
path = getenv("PWD");
if(path!=NULL) {
strcpy(path+(strlen(path)),"/temperature");
}
else {
printf("Couldn't find script\n");
exit(1);
}
printf("Executing script : %s\n",path);
if(system(path)){
perror("error\n");
}
}

After compiling the above and executing you get the output:

Executing script : /blabla/blabla/temperature
current CPU frequency is 798 MHz (asserted by call to hardware).
CPU Temperature = 51
Hard disk Temperature = 53

Cool isn't it?
But it wasn't really useful to exec the program every time to see the results...
So I modified it again to take as argument two integers.
The one was how many times to exec script and the other how many seconds to sleep between executions.
After that I told my self, why don't you make it to keep a log file for you?
So I did. I added ability to print time (to see how see the code below), and to run in a infinite loop if repeat times = -1.
I didn't make a file cos I am a little lazy, I just used the operator > to redirect output to a file!!!
And after that I though it would be useful to others if it was able to exec any script, so I modified it again to take the script name as argument.

Finally here is the final version (for me at least):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#define MAXPATH 127
#define DEFAULTVALUE 5
int main(int argc,char* argv[]){
if (argc!=4 && argc!=2) {
printf("Usage : \n %s \"script file\" \"sleeptime in sec\"
\"repeat times\"\n",argv[0]);
exit(0);
}
char *path = malloc(MAXPATH);//MAXPATH chars
path = getenv("PWD");
if(path!=NULL) {
strcpy(path+(strlen(path)),"/"); //add / to the end
strcpy(path+(strlen(path)),argv[1]); //add the script file to the end
}
else {
printf("Couldn't find path\n");
exit(1);
}
int repeat,sleep_sec,i;
if(argc==4) {
sleep_sec = atoi(argv[2]);
if(sleep_sec<0) sleep_sec = DEFAULTVALUE;
repeat = atoi(argv[3]);
if(repeat<0 && repeat!=-1) repeat = DEFAULTVALUE;
}
else {
repeat = DEFAULTVALUE;
sleep_sec = DEFAULTVALUE;
}
i=0;
time_t t;
if(repeat!= -1) {
printf("Executing script : %s %d times every %d seconds\n",
path,repeat,sleep_sec);
}
else {
printf("Executing script : %s every %d seconds\n",path,sleep_sec);
}
while( repeat == -1 || i<repeat) {
sleep(sleep_sec);
time(&t);
printf("\t%s", asctime(localtime(&t))); //print current time
fflush(stdout); //force write date and time
if(system(path)){ //execute script
perror("error\n");
}
i++;
}
printf("\n");
return 0;
}

And the output looks like that:

:/blabla/blabla # ./temperature2
Usage :
./t2 "script file" "sleeptime in sec" "repeat times"
:/blabla/blabla # ./temperature2 temperature 2 3
Executing script : /blabla/blabla/temperature 3 times every 2 seconds
Tue Jun 17 15:38:39 2008
current CPU frequency is 798 MHz (asserted by call to hardware).
CPU Temperature = 50
Hard disk Temperature = 52
Tue Jun 17 15:38:41 2008
current CPU frequency is 798 MHz (asserted by call to hardware).
CPU Temperature = 51
Hard disk Temperature = 52
Tue Jun 17 15:38:43 2008
current CPU frequency is 798 MHz (asserted by call to hardware).
CPU Temperature = 51
Hard disk Temperature = 52

:/blabla/blabla #

Now you can use it like that to keep a log file:

:/blabla/blabla # ./temperature2 temperature 30 -1 > temp_log_file.txt &
16716 <--- this is the pid of the new proccess.
:/blabla/blabla #

Now it is running in the background and you will notice the file temp_log_file.txt in the directory.

To stop the process use:

kill 16716

replace 16716 with the correct pid. If you don't remember it use ps to find it.
You may don't want to kill it as it only uses about 1kb of memory...
After all OS will send the kill signal at shutdown!

I forgot to show you my log file. Here it is.

Executing script : /blabla/blabla/temperature every 30 seconds
Tue Jun 17 15:55:04 2008
current CPU frequency is 2.00 GHz (asserted by call to hardware).
CPU Temperature = 51
Hard disk Temperature = 52
Tue Jun 17 15:55:34 2008
current CPU frequency is 798 MHz (asserted by call to hardware).
CPU Temperature = 51
Hard disk Temperature = 52
Tue Jun 17 15:56:04 2008
current CPU frequency is 798 MHz (asserted by call to hardware).
CPU Temperature = 51
Hard disk Temperature = 52
Tue Jun 17 15:56:35 2008
current CPU frequency is 2.00 GHz (asserted by call to hardware).
CPU Temperature = 51
Hard disk Temperature = 52

I hope you like. Thank you for visiting and reading my posts.
Comments appreciated.

1 comment:

Anonymous said...

nice one...like it