解析命令行参数时的奇怪行为c ++

时间:2013-03-04 15:17:43

标签: c++ command-line pipe

这是我以前从未见过的一个问题,并认为这将是值得分享的。我不知道为什么会发生这种情况。

这是我调用程序的方式:

  

./ foo -switch1 arg1 -switch2 arg2 -switch3 arg3 | arg4 | arg5 -switch4 -arg6

每个开关用于指示不同类型的参数,我会相应地解析它们。

switch3出现问题,表示arg3arg4arg5都对应同一个开关,并使用|字符进行描述。

出于某种原因,我可以完美地运行程序,但是当我尝试使用gdb进行调试时,我的程序崩溃时出现during startup, program exited with code 127错误。

这就是让我感兴趣的东西。它还说bin/bash: arg4 not found。它在第一个|字符之后立即获取参数,现在我假设它将其视为管道字符,并尝试调用bash脚本。

为什么会这样?编译器是否采用整个命令行字符串并将空格分隔的标记视为不同的参数?为什么|的解释不同?我尝试在引号arg3|arg4|arg5中添加"",它运行正常。我也尝试用-分隔它们,例如。 arg3-arg4-arg5,这也很好。

2 个答案:

答案 0 :(得分:7)

|字符在bash中具有特殊含义:它会创建pipeline

您的程序只能看到以下参数:

./foo -switch1 arg1 -switch2 arg2 -switch3 arg3

|arg4语法由bash解释为表示应该运行(不存在的)arg4命令,并且./foo的标准输出应该是用arg4标准输入。 |arg5 ...的解释方式相同。

要抑制此行为,请运行您的程序:

./foo -switch1 arg1 -switch2 arg2 -switch3 'arg3|arg4|arg5' -switch4 -arg6

(注意引号)。

答案 1 :(得分:4)

问题是|是一个管道,所以你最终试图调用shell无法找到的arg4。您需要使用其中的管道引用内容,即"arg3|arg4|arg5"

./foo -switch1 arg1 -switch2 arg2 -switch3 "arg3|arg4|arg5" -switch4 -arg6

如果您好奇,可以查看bash pitfalls。如果你没有进行大量的shell编程,你可能不会经常看到这些问题,但是当你这样做时可能需要一段时间来弄清楚发生了什么,所以从长远来看,学习shell编程的更多信息会有所帮助。我记得打过3号,我第一次找到一个好的解决方案花了一些时间。