使程序接受带空格的命令行参数需要什么?
还有另一个编辑:我刚认识到该程序是从一个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 / pod / movies / some。
任何人都知道这里有什么问题吗?我认为我不是第一个遇到这个问题的人(尽管我在这里找不到相关的问题)。
答案 0 :(得分:5)
在您的包装器脚本中用./data_sniffer.bin $*
替换./data_sniffer.bin "$@"
的使用,并且应以正确的方式转发参数。
有关$*
,$@
和"$@"
之间差异的更多信息,请here。
这个问题的作者完全改变了它并提出了有关此事的更多信息,我会让所有已经写好的内容但请记住这是在他/她的最后一次编辑之前写的..
argv
.. 作为开发者,您并不需要太多的东西,我会说它需要 nothing 来诱惑(并且更加真实)。
传递给应用程序的参数由执行二进制文件的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]: %s\n", argv[1]);
来验证其内容?
您确定使用正确的命令行参数调用正确的二进制文件吗?
可悲的是,唯一合理的做法就是你做错了什么。但是,如果没有关于该问题的进一步信息,我们无法回答。
我发现很难相信你的 shell 中有一个错误,即使这当然是可能的 - 我对此表示怀疑。
将命令行解析为argv
并不是您作为开发人员应该担心的事情,您不必为二进制本身实现强制执行的功能处理其中的空格。
答案 1 :(得分:4)
在我的CentOS 5.3中,我做了一个测试。
#include <stdio.h>
int main(int argc, char** argv)
{
printf("argc=%d\n", argc);
int i = 0;
for(i = 0; i<argc; i++)
{
printf("argv[%d]=%s\n", 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”都在工作。