Shell 为什么不是';我的蚊虫';什么是杰出的文件描述符?

Shell 为什么不是';我的蚊虫';什么是杰出的文件描述符?,shell,ada,gnat,Shell,Ada,Gnat,作为一个小项目的一部分,我正在用Ada编写一个shell。因此,当我调查系统调用时,我了解到有三种方法可以做到这一点 POSIX系统调用,这可能是最不可靠的 将参数传递给C的system(),我并不想这样做,因为这是关于用Ada而不是C编写仿真器的 使用GNAT的运行库 我选择了最后一个选项,认为这是最“像Ada”的选择。我在RosettaCode上找到了一个代码片段。在将“cmd.exe”更改为“ls”并删除第二个参数定义后,我复制并粘贴了它,并对其进行了编译。但是,当我运行可执行文件时,什么

作为一个小项目的一部分,我正在用Ada编写一个shell。因此,当我调查系统调用时,我了解到有三种方法可以做到这一点

  • POSIX系统调用,这可能是最不可靠的
  • 将参数传递给C的system(),我并不想这样做,因为这是关于用Ada而不是C编写仿真器的
  • 使用GNAT的运行库
  • 我选择了最后一个选项,认为这是最“像Ada”的选择。我在RosettaCode上找到了一个代码片段。在将“cmd.exe”更改为“ls”并删除第二个参数定义后,我复制并粘贴了它,并对其进行了编译。但是,当我运行可执行文件时,什么也没有发生。shell直接返回到提示符。我在两台不同的电脑上测试过这个,一台运行Fedora21,另一台运行Debian Jessie。下面是我为测试它所做的:

    • 查看是否是缺少参数字符串导致的
    • 检查GNAT库中的任何文件描述符是否命名错误
    • 将stderr和stdin重定向到stdout只是为了查看GNAT是否将它们转储到错误的FD
    • 仔细查看了System.OS_lib库文件,似乎没有任何原因
    • 谷歌搜索了它,但GNAT在GCC网站上自己的页面记录得非常糟糕
    目前,我在准备shell时使用C.Interface系统,但我对此不满意。我是Ada的新成员,现在才修修补补了一个月左右,所以如果有什么Ada的智慧可以帮助我的话,我不会参与其中


    更新:我尝试使用绝对路径运行它,无论是到/usr/bin还是/bin位置,但都无法运行。有趣的是,操作系统返回的结果代码是1,但我不知道这意味着什么。快速搜索表明它是针对“所有常规错误”,而另一个站点则表明它是针对“不正确的函数”。

    如果没有shell,您需要自己搜索路径,或者为所需的可执行文件指定完整路径:

    Spawn (
       Program_Name => "/bin/ls",
       …
    );
    
    $ which ls
    /bin/ls
    
    我试过用绝对路径运行它,
    /usr/bin
    /bin
    位置都不起作用

    使用
    which
    确定可执行文件的完整路径:

    Spawn (
       Program_Name => "/bin/ls",
       …
    );
    
    $ which ls
    /bin/ls
    

    我不得不稍微调整RosettaCode示例,以便在Debian Linux上运行
    /bin/ls
    ,但它确实按预期运行

    with Ada.Text_IO;     use Ada.Text_IO;
    with Gnat.OS_Lib;   use Gnat.OS_Lib;
    
    procedure Execute_Synchronously is
       Result    : Integer;
       Arguments : Argument_List :=
                     (  1=> new String'("-al")
                     );
    begin
       Spawn
       (  Program_Name           => "/bin/ls",
          Args                   => Arguments,
          Output_File_Descriptor => Standout,
          Return_Code            => Result
       );
       for Index in Arguments'Range loop
          Free (Arguments (Index)); 
       end loop;
    end Execute_Synchronously;
    
    变化:

  • my Gnat(Debian Jessie提供的FSF Gnat 4.92)警告了
    System.OS_Lib
    ,建议改为
    Gnat.OS_Lib
    。(这只是重命名System.OS_Lib…为什么?
    System.OS_Lib注释:
  • --注意:此软件包位于系统层次结构中,因此可以直接使用
    --被其他预定义包使用。用户可通过
    --GNAT.OS_Lib(文件g-OS_Lib.ads)中此包的重命名

  • 程序名,包括路径
  • 我第一次运行它时,它显示了“ls”本身的详细信息,因为它有自己的名称作为第一个参数,所以我删除了它以查看当前目录
  • 注:

  • 可用子程序及其参数的最佳信息通常在“adainclude”中的包规范中文件夹:这是
    /usr/lib/gcc/x86\u 64-linux-gnu/4.9/adainclude
    ,在我的Debian安装中,
    定位system.ads
    将找到你的。具体文件是:
    s-os\u lib.ads
    用于导出Spawn和Standout的
    system.os\u lib
    ,以及
    a-textio.ads
    用于Ada.Text\IO
  • Standout
    不是访问标准输出的首选方式:它是一个文件描述符(整数),首选方式是
    Ada.Text\u IO
    中的
    Standard\u Output
    函数,该函数返回一个文件。但是,对于接受文件的
    Spawn
    ,似乎没有过载(我也不希望在这个低级库中有一个)因此这里使用低级文件描述符

  • 在考虑过要添加PATH变量后,我觉得自己没有尝试过这个,我会尝试这个soon@Bronze:您可以使用
    Getenv
    查询继承的
    路径