【问题标题】:execlp command doesn't take into account the asterisk wildcardexeclp 命令不考虑星号通配符
【发布时间】:2014-08-29 13:19:00
【问题描述】:

这个小命令:

execlp("/bin/echo", "echo", "*", ">", "toto", 0) 

在终端打印* > toto,但我希望它在文件toto中打印echo *的结果。

命令:system("echo * > toto")  运行良好,但我想使用 execlp 命令,我做错了什么?

提前谢谢你。

【问题讨论】:

  • 我认为execlp 试图直接执行命令echo。要执行您想要的命令,需要转到 shell/命令解释器。

标签: c unix command


【解决方案1】:

尖括号 ('>') 重定向是特定于 shell 的。

你可以这样做,例如:

execlp("/bin/sh", "/bin/sh", "-c", "/bin/echo * > toto", NULL);

请注意,这会调用 2 个与 shell 相关的特定行为:

  1. * 通配符:星号通配符将被扩展(shell,非常重要)到当前目录下的所有文件;和
  2. > 重定向:echo 命令的标准输出将被重定向到文件(或管道)toto

如果您想在 C 中进行相同类型的重定向(即不诉诸执行 shell),您必须:

// open the file
int fd = open("toto", "w");

// reassign your file descriptor to stdout (file descriptor 1):
dup2(fd, 1); // this will first close file descriptor, if already open

// optionally close the original file descriptor (as it were duplicated in fd 1 and is not needed anymore):
close(fd);

// finally substitute the running image for another one:
execlp("/bin/echo", "echo", "*" 0);

请注意,您仍会将“*”写入文件。

编辑:execlp 的第一个参数实际上是要运行的可执行文件,将替换当前运行的进程的文件映像。在第一个参数之后是完整的argv 数组,其中必须包括argv[0]。我已经编辑了上面的代码以反映这一点。一些程序使用这个argv[0] 来改变它的个性(例如,busybox 是实现lsechocat 和许多其他unix 命令行实用程序的单个可执行文件); bash 以及与 /bin/sh 链接的任何内容肯定就是这种情况。

【讨论】:

  • 感谢您的回复!如果我运行这个命令: execlp("/bin/sh", "-c", "/bin/echo", "*", ">", "toto", (char *) 0);我有以下错误:/bin/echo: 1: /bin/echo: Syntax error: word unexpected (expecting ")") 如果我用 bash 替换 sh,我有这个错误:/bin/echo: /bin/ echo: 无法执行二进制文件,你知道为什么吗?
  • @user3683807 我更正了对 execlp 的调用; /bin/sh 和 /bin/bash 都期望 '-c' 有一个参数;他们会自己解析命令行。
  • 我尝试了很多类似的命令,但仍然无法使用 execlp("/bin/sh", "-c", "/bin/echo * > toto", NULL) ;我有以下错误:-c: 0: Can't open /bin/echo * > toto,知道吗?此外,我认为我并没有真正理解选项“-c”的作用......
  • @user3683807,shell 解释器的“-c”参数意味着“不要期望来自键盘的命令,而是从 -c 之后的下一个参数中读取它们”。
  • @user3683807,现在我明白了:您需要复制参数“/bin/sh”。我将编辑答案来解释这一点。
猜你喜欢
  • 1970-01-01
  • 2018-11-19
  • 1970-01-01
  • 2019-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-22
  • 1970-01-01
相关资源
最近更新 更多