• shell脚本之位于第一行的#!


     

    当Shell执行一个程序时,会要求UNIX内核启动一个新的进程(process),以便在该进程里执行所指定的程序。内核知道如何为编译型程序做这件事。我们的nusers Shell脚本并非编译型程序;当Shell要求内核执行它时,内核将无法做这件事,并回应“not executable format file”(不是可执行的格式文件)错误信息。Shell收到此错误信息时,就会说“啊哈,这不是编译型程序,那么一定是Shell脚本”,接着会启动一个新的 /bin/sh(标准Shell)副本来执行该程序。

     
        当系统只有一个Shell时,“退回到/bin/sh”的机制非常方便。但现行的UNIX系统都会拥有好几个Shell,因此需要通过一种方式,告知UNIX内核应该以哪个Shell来执行所指定的Shell脚本。事实上,这么做有助于执行机制的通用化,让用户得以直接饮用任何的程序语言解释器,而非只是一个命令Shell。方法是,通过脚本文件中特殊的第一行来设置:在第一行的开头处使用#!这两个字符。
     
        当一个文件中开头的两个字符是#!时,内核会扫描该行其余部分,看是否存在可用来执行程序的解释器的完整路径。(中间如果出现任何空白符号都会略过。)此外,内核还会扫描是否有一个选项要传递给解释器。内核会以被指定的选项来引用解释器,再搭配命令行的其他部分。举例来说,假设有一个csh脚本(/bin/csh是C Shell的命令解释器),名为/usr/ucb/whizprog,它的第一行如下所示:
            #! /bin/csh -f
     
        再者,如果Shell的查找路径(后面会介绍)里有/usr/ucb,当用户键入 whizprog -q /dev/tty01 这条命令,内核解释#!这行后,便会以如下的方式来引用csh:
            /bin/csh -f /usr/ucb/whizprog -q /dev/tty01
     
        这样的机制让我们得以轻松地引用任何的解释器。例如我们可以这样引用独立的awk程序:
            #! /bin/awk -f
            此处是awk程序
     
        Shell脚本通常一开始都是#! /bin/sh。如果你的 /bin/sh 并不符合POSIX标准,请将这个路径改为符合POSIX标准的Shell。下面是几个初级的陷阱(gotchas),请特别留意:
    • 当今的系统,对#!这一行的长度显示从63到1024个字符(character)都有。请尽量不要超过64个字符
    • 在某些系统上,命令行部分(也就是要传递给解释器执行的命令)包含了命令的完整路径名称。不过有些系统却不是这样;命令行的部分会原封不动地传给程序。因此,脚本是否具有可移植性取决于是否有完整的路径名称。
    • 别在选项(option)之后放置任何空白,因为空白也会跟着选项一起传递给引用的程序。
    • 你需要知道解释器的完整路径明后才能。这样可以用来规避可移植性问题,因为不同的厂商可能将同样的东西放在不同的地方(例如 /bin/awk 和 /usr/bin/awk)。
    • 一些较旧的系统上,内核不具备解释#!的能力,有些Shell会自行处理,这些Shell对于#!与紧随其后的解释器名称之间是否可以有空白,可能是有不同的解释。
     
        POSIX标准对#!的行为模式保留未定义(unspecified)状态。此状态是“只要一直保持POSIX兼容性,这是一个扩展功能”的标准说法。
     
        本系列接下来所有脚本开头都会有#!行,下面是修订过的nusers程序:
     
    [many@avention my_sh]$ cat nusers
    #! /bin/sh -
     
    echo "开始统计用户数..."
    who | wc -l
    echo "统计用户数结束..."
     
        选项 - 表示没有Shell选项;这是基于安全上的考虑,可以避免某种程度的欺骗式攻击(spoofing attack)。
     
    文章引用地址 https://www.cnblogs.com/avention/p/9661402.html
     
  • 相关阅读:
    C# savefiledialog 保存文件后 再操作数据库 提示数据库文件路径错误
    转:在C#中使用Nullable类型
    转:Global.asax通过Application_BeginRequest()事件实现访问链接的静态地址映射
    DZ7.0自动伸缩广告
    转:使用HttpModule来实现sql的防注入
    转:System.Web.UI.Page类的构造函数的执行时机
    使用ISAPI_Rewrite做简单实用的301重定向
    IIS7添加ASP.NET网站碰到的问题
    IE9 崩溃的解决方法
    利用ZEND Studio与Zend server对PHP WEB进行调试
  • 原文地址:https://www.cnblogs.com/xzlq/p/9968247.html
Copyright © 2020-2023  润新知