首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用C编写可移植的命令行包装器

用C编写可移植的命令行包装器
EN

Stack Overflow用户
提问于 2009-07-07 23:07:44
回答 6查看 2.4K关注 0票数 12

我正在编写一个名为perl5i的perl模块。它的目标是在一个模块中修复一系列常见的Perl问题(使用许多其他模块)。

要在命令行中调用它,您可以这样写:perl -Mperl5i -e 'say "Hello"',我认为这太冗长了,所以我想提供一个perl5i包装器,这样您就可以编写perl5i -e 'say "Hello"'了。我还希望人们能够用#!/usr/bin/perl5i编写脚本,所以它必须是编译好的C程序。

我认为我所要做的就是将"-Mperl5i“放在参数列表的前面,然后调用perl。这就是我试过的。

代码语言:javascript
复制
#include <unistd.h>
#include <stdlib.h>

/*
 * Meant to mimic the shell command
 *     exec perl -Mperl5i "$@"
 *
 * This is a C program so it works in a #! line.
 */

int main (int argc, char* argv[]) {
    int i;
    /* This value is set by a program which generates this C file */
    const char* perl_cmd = "/usr/local/perl/5.10.0/bin/perl";
    char* perl_args[argc+1];
    perl_args[0] = argv[0];
    perl_args[1] = "-Mperl5i";

    for( i = 1;  i <= argc;  i++ ) {
        perl_args[i+1] = argv[i];
   }

   return execv( perl_cmd, perl_args );
}

Windows使这种方法变得更加复杂。显然,Windows中的程序没有传递一组参数,它们将所有参数作为单个字符串传递,然后进行自己的解析!因此,像perl5i -e "say 'Hello'"这样的东西就变成了perl -Mperl5i -e say 'Hello',而Windows不能处理缺少引用的问题。

那么,我该如何处理呢?在Windows上用引号和转义符将所有内容括起来?有没有图书馆帮我处理这件事?有没有更好的方法?我能不能不在Windows上生成一个C程序,然后把它写成一个perl包装器,因为它不支持#!不管怎么说?

更新:更清楚的是,这是随附的软件,因此需要使用特定外壳或调整外壳配置(例如alias perl5i='perl -Mperl5i')的解决方案不能令人满意。

EN

回答 6

Stack Overflow用户

发布于 2009-07-07 23:20:52

对于Windows,请使用批处理文件。

perl5i.bat

代码语言:javascript
复制
@echo off
perl -Mperl5i %*

%*是减去%0后的所有命令行参数。

在Unixy系统上,一个类似的shell脚本就足够了。

更新:

我认为这是可行的,但我不是shell向导,我也没有现成的*nix系统可供测试。

perl5i

代码语言:javascript
复制
#!bash

perl -Mperl5i $@

再次更新

好了!现在我正确地理解了你的#!注释。我的shell脚本可以从命令行界面运行,但不能在#!行中运行,因为#!foo要求foo是一个二进制文件。

忽略以前的更新。

看起来Windows把一切都复杂化了。我认为你最好是使用一个批处理文件。

你可以use a file association,把.p5iperl -Mperl5i %*联系起来。当然,这意味着在注册表中胡乱操作,最好避免使用IMO。最好在文档中包含有关如何手动添加关联的说明。

又一次更新

您可能想看看parl是如何做到这一点的。

票数 4
EN

Stack Overflow用户

发布于 2009-07-08 13:15:39

我无法重现你所描述的行为:

代码语言:javascript
复制
/* main.c */

#include <stdio.h>

int main(int argc, char *argv[]) {
    int i;
    for (i = 0; i < argc; i++) {
        printf("%s\n", argv[i]);
    }
    return 0;
}

C:\> ShellCmd.exe a b c
ShellCmd.exe
a
b
c

这是在Visual Studio 2005中实现的。

票数 2
EN

Stack Overflow用户

发布于 2009-07-08 15:20:59

Windows总是奇特的情况。就我个人而言,我不会尝试为Windows环境异常编写代码。一些替代方案是使用"bat包装器“或ftype/assoc注册表hacks作为文件扩展名。

Windows在从DOS命令shell运行时会忽略shebang行,但在Apache for Windows中对Perl执行CGI时却使用它。我厌倦了直接在我的web程序中编写#!c:/perl/bin/perl.exe,因为在迁移到*nix环境时会出现可移植性问题。相反,我在我的工作站上创建了一个c:\usr\bin目录,并从其默认位置复制了perl.exe二进制文件,对于AS Perl,通常是c:\perl\bin,对于Strawberry Perl,通常是c:\strawberry\perl\bin。因此,在Windows的web开发模式下,我的程序在迁移到Linux/UNIX webhost时不会崩溃,而且我可以使用标准的shebang行"#!/usr/bin/perl -w“,而不必在部署之前抓狂。:)

在DOS命令行管理程序环境中,我要么显式地设置路径,要么使用嵌入式开关-Mperl5i创建一个指向实际perl.exe二进制文件的ftype。shebang行被忽略。

代码语言:javascript
复制
ftype p5i=c:\strawberry\perl\bin\perl.exe -Mperl5i %1 %*
assoc .pl=p5i

然后,在DOS命令行中,你可以直接调用"program.pl“来代替"perl -Mperl5i program.pl”

因此,只需输入Perl程序本身的名称,"say“语句就可以在5.10中工作,并且它也可以接受数量可变的命令行参数。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1095309

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档