Linux 如何区分可执行文件还是shell脚本,调用的流程是什么样子的

发布于 2021-11-27 13:43:12 字数 173 浏览 985 评论 7

Linux 如何区分可执行文件还是shell脚本,调用的流程是什么样子的。

比如说:

    ./script # 这个是一个shell脚本

    ./hello # 这个是一个C程序

linux是区分的。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

旧伤慢歌 2021-12-01 20:26:34

linux shell 在执行的时候,如何区分脚本,或者 elf文件?两者内容是完全不一样的,但是文件名可以是一样的。而为什么linux能区分出来?因为shell会优先调用linux execve执行,如果失败,则检测是否按照#!开头,如果是,则使用指定解释器,否则使用默认sh执行。如果都失败,则报错。

噩梦成真你也成魔 2021-12-01 20:26:06

用Linux发行版自带file命令就好了.

file /bin/ls

/bin/ls: ELF 64-bit LSB  executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=xxx, stripped

file /etc/rc.local

/etc/rc.local: POSIX shell script, ASCII text executable

最偏执的依靠 2021-12-01 20:19:31

file命令就一目了然了

泛泛之交 2021-12-01 19:48:51

运行sh a.sh,表示我使用sh来解释这个脚本,楼上已经演示了,可以不要执行权限;

如果我直接运行./a.sh,首先你会查找脚本第一行是否指定了解释器,如果没指定,那么就用当前系统默认的
shell
(大多数linux默认是bash),如果指定了解释器,那么就将该脚本交给指定的解释器

比如a.run文件内容是这个:

#!/usr/bin/python print("This is Python script")
别再吹冷风 2021-12-01 16:54:04

BASH(1)                  USER COMMANDS                    BASH(1)

     If the program is a file beginning with #!, the remainder of

     the  first  line  specifies  an interpreter for the program.

     The shell executes the specified  interpreter  on  operating

     systems  that  do  not  handle  this executable format them-

     selves.  The arguments to the interpreter consist of a  sin-

     gle  optional argument following the interpreter name on the

     first line of the program, followed by the name of the  pro-

     gram, followed by the command arguments, if any.

叹沉浮 2021-11-30 07:38:22

http://stackoverflow.com/questions/23295724/how-does-linux-execute-a-file

Yes, linux requires file to be in some supported (registered) format and execute bit set in order to execute it. Most files in Linux has either ELF format, or "shebang" format (two first symbols of them are #! and then path to interpreter is written, used by bash, perl, python and most other scripts). Sometimes text files are allowed to execute as shell scripts, e.g. when you do ./script from bash (handled not by kernel, but by bash shell).

德意的啸 2021-11-29 12:25:08
/**/
static int
zexecve(char *pth, char **argv, char **newenvp)
{
    int eno;
    static char buf[PATH_MAX * 2];
    char **eep;

    unmetafy(pth, NULL);
    for (eep = argv; *eep; eep++)
	if (*eep != pth)
	    unmetafy(*eep, NULL);
    buf[0] = '_';
    buf[1] = '=';
    if (*pth == '/')
	strcpy(buf + 2, pth);
    else
	sprintf(buf + 2, "%s/%s", pwd, pth);
    zputenv(buf);
#ifndef FD_CLOEXEC
    closedumps();
#endif

    if (newenvp == NULL)
	    newenvp = environ;
    winch_unblock();
	//交托给linux执行ELF,OUT等格式的本地文件,这是通过文件的MAGIC来实现的
    execve(pth, argv, newenvp);

    /* If the execve returns (which in general shouldn't happen),   *
     * then check for an errno equal to ENOEXEC.  This errno is set *
     * if the process file has the appropriate access permission,   *
     * but has an invalid magic number in its header.               */
    if ((eno = errno) == ENOEXEC || eno == ENOENT) {
	char execvebuf[POUNDBANGLIMIT + 1], *ptr, *ptr2, *argv0;
	int fd, ct, t0;

	if ((fd = open(pth, O_RDONLY|O_NOCTTY)) >= 0) {
	    argv0 = *argv;
	    *argv = pth;
	    execvebuf[0] = '';
	    ct = read(fd, execvebuf, POUNDBANGLIMIT);
	    close(fd);
	    if (ct >= 0) {
		if (execvebuf[0] == '#') {
		    if (execvebuf[1] == '!') {
			for (t0 = 0; t0 != ct; t0++)
			    if (execvebuf[t0] == 'n')
				break;
			while (inblank(execvebuf[t0]))
			    execvebuf[t0--] = '';
			execvebuf[POUNDBANGLIMIT] = '';
			for (ptr = execvebuf + 2; *ptr && *ptr == ' '; ptr++);
			for (ptr2 = ptr; *ptr && *ptr != ' '; ptr++);
			if (eno == ENOENT) {
			    char *pprog;
			    if (*ptr)
				*ptr = '';
			    if (*ptr2 != '/' &&
				(pprog = pathprog(ptr2, NULL))) {
				argv[-2] = ptr2;
				argv[-1] = ptr + 1;
				winch_unblock();
				//执行指定解释器
				execve(pprog, argv - 2, newenvp);
			    }
			    zerr("%s: bad interpreter: %s: %e", pth, ptr2,
				 eno);
			} else if (*ptr) {
			    *ptr = '';
			    argv[-2] = ptr2;
			    argv[-1] = ptr + 1;
			    winch_unblock();
			    execve(ptr2, argv - 2, newenvp);
			} else {
			    argv[-1] = ptr2;
			    winch_unblock();
			    execve(ptr2, argv - 1, newenvp);
			}
		    } else if (eno == ENOEXEC) {
			argv[-1] = "sh";
			winch_unblock();
			//如果查询不到,则使用默认的shell执行
			execve("/bin/sh", argv - 1, newenvp);
		    }
		} else if (eno == ENOEXEC) {
		    for (t0 = 0; t0 != ct; t0++)
			if (!execvebuf[t0])
			    break;
		    if (t0 == ct) {
			argv[-1] = "sh";
			winch_unblock();
			execve("/bin/sh", argv - 1, newenvp);
		    }
		}
	    } else
		eno = errno;
	    *argv = argv0;
	} else
	    eno = errno;
    }
    /* restore the original arguments and path but do not bother with *
     * null characters as these cannot be passed to external commands *
     * anyway.  So the result is truncated at the first null char.    */
    pth = metafy(pth, -1, META_NOALLOC);
    for (eep = argv; *eep; eep++)
	if (*eep != pth)
	    (void) metafy(*eep, -1, META_NOALLOC);
    return eno;
}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文