通过shell包装脚本将带有空格的命令行参数传递给C程序



如何使程序接受带有空格的命令行参数?

还有一个编辑:我刚刚认识到程序是从一个shell脚本启动的,该脚本为程序的执行设置了环境。由于存在一些外部库,LD_LIBRARY_PATH被设置为当前工作目录:

#!/bin/sh
ARCH=`uname -m`
export LD_LIBRARY_PATH=".:lib/magic/linux-${ARCH}"
./data_sniffer.bin $*
exit $?

这个问题肯定与$*有关。有什么解决方案可以正确转发命令行参数吗?

以下是来自main():的代码片段

if (stat(argv[1], &lStat) != 0)
{   
    fprintf(stderr, "Cannot stat(2) given file: %s. n", argv[1]);
    return EXIT_FAILURE;
}   

我用以下参数启动我的程序:

./data_sniffer /mnt/pod/movies/some test movie file.avi

生成的错误消息如下所示:无法对给定的文件进行stat(2):/mnt/podmovies/some。

有人知道这里出了什么问题吗?我想我不是第一个有这个问题的人(尽管我在这里找不到相关的问题)。

在包装脚本中将./data_sniffer.bin $*的使用替换为./data_sniffer.bin "$@",并且应以正确的方式转发参数。

关于$*$@"$@"之间的差异,可以在这里找到更多信息。


这个问题的作者完全改变了它,并提供了更多关于此事的信息,我会让已经写的一切都保持原样,但请记住,这是在他/她上次编辑之前写的


关于argv

作为一名开发人员,它不需要你付出太多,我很想(而且更真实)说它不需要任何东西。

传递给应用程序的参数由执行二进制文件的shell处理,在下面这样做肯定会按照您希望的方式工作(尽管我觉得奇怪的是,您声称当前shell没有正确处理' '):

./data_sniffer '/mnt/pod/movies/some test movie file.avi'
./data_sniffer /mnt/pod/movies/some test movie file.avi
# there should be no difference between the two

我的推荐

  • 你有没有试过在main的开头做printf ("argv[1]: %sn", argv[1]);来验证它的内容?

  • 您确定使用正确的命令行参数调用了正确的二进制文件吗?

可悲的是,唯一合理的写作方式就是你做错了什么。然而,如果没有关于这个问题的进一步信息,我们无法回答。

我发现很难相信你的外壳中有漏洞,尽管这当然是可能的-我对此表示怀疑。


命令行解析为argv不是开发人员应该担心的事情,二进制文件本身不需要实现强制功能来处理其参数中的空格。

在我的CentOS 5.3中,我做了一个测试。

#include <stdio.h>
int main(int argc, char** argv)
{
        printf("argc=%dn", argc);
        int i = 0;
        for(i = 0; i<argc; i++)
        {   
                printf("argv[%d]=%sn", i, argv[i]);
        }   
        return 0;
}

然后用不同的参数运行它:

[root@dw examples]# ./a.out a b c
argc=4
argv[0]=./a.out
argv[1]=a
argv[2]=b
argv[3]=c
[root@dw examples]# ./a.out 'a b c'
argc=2
argv[0]=./a.out
argv[1]=a b c
[root@dw examples]# ./a.out a b c
argc=2
argv[0]=./a.out
argv[1]=a b c
[root@dw examples]# ./a.out "a b c"
argc=2
argv[0]=./a.out
argv[1]=a b c

看起来像(1)"a b c";(2) a\b\c;(3) "a b c"都在起作用。

最新更新