作为一个小项目的一部分,我正在用 Ada 编写一个 shell。因此,当我研究系统调用时,我了解到有三种方法可以做到这一点。
- POSIX 系统调用,这可能是最不可靠的。
- 将参数传递给 C 的 system(),我实际上并不想这样做,因为这是关于用 Ada 而不是 C 编写模拟器。
- 使用 GNAT 的运行时库。
我选择了最后一个选项,认为这是最“像 Ada”的选择。我在 RosettaCode here 上找到了一个代码片段。在将“cmd.exe”更改为“ls”并删除第二个参数定义后,我复制并粘贴了它并编译了它。但是,当我运行可执行文件时,没有任何反应。 shell 直接返回到提示符。我在两台不同的计算机上对此进行了测试,一台运行 Fedora 21,另一台运行 Debian Jessie。这是我所做的测试:
- 查看是否缺少参数字符串导致的
- 检查 GNAT 库中的任何文件描述符是否命名错误
- 将 stderr 和 stdin 重定向到 stdout,只是为了查看 GNAT 是否将它们转储到错误的 FD。
- 仔细查看了System.OS_lib库文件,似乎没有什么原因。
- 用 Google 搜索了一下,但 GNAT 在 GCC 网站上的页面记录非常少。
目前我正在使用C.Interface系统来准备我的shell,但我对此并不满意。我是 Ada 新手,现在才对它进行了一个月左右的修改,所以如果这里有某种 Ada 智慧可以帮助我,我不会参与其中。
更新:我尝试使用绝对路径运行它,无论是/usr/bin 还是/bin 位置,但它不起作用。有趣的是,操作系统返回的结果码是1,但我不知道这意味着什么。快速搜索表明它用于“所有一般错误”,另一个网站表明它用于“不正确的功能”。
最佳答案
我必须稍微调整 RosettaCode 示例才能运行 /bin/ls
在 Debian Linux 上,但它确实按预期运行...
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;
更改:
- 我的 Gnat(来自 Debian Jessie 的 FSF Gnat 4.92)警告
System.OS_Lib
,推荐Gnat.OS_Lib
反而。 (这只是重命名 System.OS_Lib ....为什么???
System.OS_Lib 注释:
-- Note: this package is in the System hierarchy so that it can be directly
-- be used by other predefined packages. User access to this package is via
-- a renaming of this package in GNAT.OS_Lib (file g-os_lib.ads).
- 程序名称,包括路径。
- 参数。我第一次运行它时,它显示了“ls”本身的详细信息,因为它被赋予了自己的名称作为第一个参数,所以我删除了它以查看当前目录。
注释:
- 可用子程序及其参数的最佳信息通常位于“adainclude”文件夹中的包规范本身:这是
/usr/lib/gcc/x86_64-linux-gnu/4.9/adainclude
在我的 Debian 安装中,locate system.ads
会找到你的。具体文件为:s-os_lib.ads
对于System.OS_Lib
导出 Spawn 和 Standout,以及a-textio.ads
对于 Ada.Text_IO。 -
Standout
不是访问标准输出的首选方式:它是文件描述符(整数),首选方式是Standard_Output
来自Ada.Text_IO
的函数它返回一个文件。然而Spawn
似乎没有过载它需要一个文件(我也不希望在这个低级库中出现),因此这里使用较低级的文件描述符。
关于shell - 为什么我的 GNAT 的杰出文件描述符不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32663224/