Perl scripts on systems without "#!"

Brandon S. Allbery allbery at NCoast.ORG
Sun Nov 5 05:51:16 AEST 1989


As quoted from <1989Nov4.180708.26446 at NCoast.ORG> by allbery at NCoast.ORG (Brandon S. Allbery):
+---------------
| Actually, csh looks for # as the first character of a script and passes it to
| sh if it doesn't find the #.
+---------------

If csh fails to exec() a program, it checks for an alias called "shell" and,
if found, prepends the value of the alias to the command and re-exec()'s it.
You can not use any of the standard alias/history modifiers and the program
called by the alias must be a full pathname.

Here's a program which I've compiled and tested, which uses the "alias shell"
approach.  Compile it, install it somewhere, and alias "shell" to the full
pathname of the executable, then enjoy a working #! and not having to worry
about the wrong shell executing your scripts.  I used to have a program called
"bexec" which purported to do this, but various versions did not work right or
took the wrong approach, or did more than most people really need (like
attempting to recognize RM/COBOL objects).  This is simpler and cleaner.

++Brandon

-------------------------------------------------------------------------------
#include <stdio.h>

#define SHELL		"/bin/sh"

extern void exit();
extern FILE *fopen();
extern void perror();
extern int fclose();
extern char *fgets();
extern int fprintf();
extern char *malloc();
extern int execve();

main(argc, argv, envp)
    char **argv, **envp;
{
    FILE *fp;
    char hashbang[1024];
    register char *cp;
    int nargc;
    char **nargv;

    if (argc < 2)
	exit(-1);
    if (!(nargv = (char **) malloc((argc + 2) * sizeof *nargv)))
    {
	perror(argv[1]);
	exit(-1);
    }
    if (!(fp = fopen(argv[1], "r")))
    {
	perror(argv[1]);
	exit(-1);
    }
    if (!fgets(hashbang, sizeof hashbang, fp))
    {
	(void) fclose(fp);
	(void) fprintf(stderr, "%s: cannot read\n", argv[1]);
	exit(-1);
    }
    (void) fclose(fp);
    if (hashbang[0] != '#' || hashbang[1] != '!')
    {
	argv[0] = SHELL;
	(void) execve(SHELL, argv, envp);
	perror(SHELL);
	exit(-1);
    }
    for (cp = hashbang + 2; *cp && *cp == ' '; cp++)
	;
    if (!*cp)
    {
	(void) fprintf(stderr, "%s: malformed #! line\n", argv[1]);
	exit(-1);
    }
    nargc = 1;
    for (nargv[0] = cp; *cp && *cp != ' ' && *cp != '\n'; cp++)
	;
    if (*cp)
	*cp++ = '\0';
    while (*cp == ' ')
	cp++;
    if (*cp && *cp != '\n')
    {
	nargv[nargc++] = cp;
	while (*cp && *cp != '\n')
	    cp++;
	*cp = '\0';
    }
    for (; argc; argc--)
	nargv[nargc + argc - 1] = argv[argc];
    (void) execve(nargv[0], nargv, envp);
    perror(nargv[0]);
    exit(-1);
}
-- 
Brandon S. Allbery    allbery at NCoast.ORG, BALLBERY (MCI Mail), ALLBERY (Delphi)
uunet!hal.cwru.edu!ncoast!allbery ncoast!allbery at hal.cwru.edu bsa at telotech.uucp
*(comp.sources.misc mail to comp-sources-misc[-request]@backbone.site, please)*
*Third party vote-collection service: send mail to allbery at uunet.uu.net (ONLY)*
>>>	     The *.aquari* debate: news.groups gone news.playpen	    <<<



More information about the Alt.sources mailing list