如何使程序接受带有空格的命令行参数?
还有一个编辑:我刚刚认识到程序是从一个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"都在起作用。