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