how do I exec() a script

Martin Weitzel martin at mwtech.UUCP
Fri Jun 29 19:22:50 AEST 1990


In article <1990Jun27.225015.1956 at virtech.uucp> cpcahil at virtech.UUCP (Conor P. Cahill) writes:
>In article <661 at kps.UUCP> llj at kps.se (Leif Ljung /DP) writes:
>>I have a program that I want to do a general exec(2) sometimes
>>executing a binary program, sometimes a shell-script preferably
>>using PATH.
>>Say I have the program `prog' - if this is a script I add the
>>'#! /bin/sh' at the top. Can I exec(2) that? No.
>
>The correct way to do this (one that will work on systems that understand
>the "#!" and those that don't) is as follows:

Though I usually appreciate Conors experience and good advice, I must
object this time:

>	place "#!/bin/sh" as the first line for the program.

Well, there are some good arguments in favor for a first line
that starts with a colon (:) in shell scripts. At least this
helps in some (IMHO brain damaged) C shells that consider every
text file which starts with a hash (#) to be a C-shell script.
(I've had some discussions in the past, if it was "legal" for
the bourne shell to add #-comments, after the C-shell "invented"
them and obviously claimed exclusive rights to use them ...)

>	in the code that you wish to exec the program do the following:
>
>		execvp("prog",argv);  /* argv is setup accordingly */
>
>		/*
>		 * if we get here, prog was not executed by the kernel,
>		 * so this system doesn't understand "#!" and we must call
>		 * the shell ourselves
>		 */

Wrong: At least in SysV(%) for which I can check this out right now,
the facts are that execvp() executes a shell if the given file
name turns out to be a text file with appropriate x-bits set.

THIS DOESN'T DEPEND ON THE FIRST LINE OF THE TEXT-FILE!

Behavior differs with "execv()", which will not only do *no* path
search, but also never execute a text file, regardless of what the
first line contains (I'm aware the latter was not what Conor claimed).

%: If memory serves, behaviour was the same in SysIII-derived XENIX.

>		arg_str[0] = '\0';	
>		for(i=0; argv[i] != NULL; i++)
>			strcat(arg_str,argv[i]);

WRONG (forgets to embed blanks or some other IFS-seperator) and
DANGEROUS - at least you should count the length of your arguments
and allocate space for arg_str dynamically. (I hope that it was
not meant this way: As I exec anyway, I may leave total desaster
behind me :-).)

>
>		sh_argv[0] = "sh";
>		sh_argv[1] = "-c";
>		sh_argv[2] = arg_str;
>		sh_argv[3] = (char *)0;
>		execvp("sh",sh_argv);
>
>-c is used so sh will use PATH to find the program.

Yes, but this is only *one* of the effects of "-c". Anotherone is that
the shell fully re-interprets the arguments. If this is desirable or
not will generally depend on the problem, but as the method here was
used as substitute for exec-ing a script from the kernel, the behaviour
will differ (Again IMHO; I have no such kernel here to check this, but
I would be surprised if the kernel had not only mechanisms to exec
the program given in the first line, but also to interpret args.)

>NOTE: I did not compile or test the above code, your milage may vary.

*If* we do so many things manually here, why not open the file,
read the first line and exec a given program in case of #!prog
in the way UCB-derivates do it in the kernel?

Any volunteers to write (and compile and test!!) such code?
You should call it something like "ucb_exec" and make the same
functions available that are normaly provided by exec. This
should not be more than one day work for any halfway experienced
C-programmer.
-- 
Martin Weitzel, email: martin at mwtech.UUCP, voice: 49-(0)6151-6 56 83



More information about the Comp.lang.c mailing list