Sreemanananth Sadanand
Sreemanananth Sadanand

Reputation: 233

Strange behviour while parsing command line arguments c++

here is an issue I have never seen before and thought it would be share-worthy. Im not sure why it happens though.

This is how I invoke my program:

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

Each switch is used to indicate a different type of argument and I parse them accordingly.

The problem occurs with switch3, which indicates that arg3, arg4, arg5 all correspond to the same switch and are delineated using the | character.

For some reason, I can run the program perfectly, but when I try to debug it using gdb, My program crashes with a during startup, program exited with code 127 error.

Here's what intrigues me. It also says bin/bash: arg4 not found. It takes the argument right after the first | character, which now I assume it perceives as the pipe character, and tries to invoke a bash script.

Why does this happen??? Doesn't the compiler take the entire command line string and consider space separated tokens as different arguments? Why is the | being interpreted differently? I tried adding arg3|arg4|arg5 in inverted quotes "", and it works fine. I also tried separating them by -, eg. arg3-arg4-arg5, and this works fine too.

Upvotes: 2

Views: 198

Answers (2)

Shafik Yaghmour
Shafik Yaghmour

Reputation: 158449

The problem is that | is a pipe so you end up trying to call arg4 which the shell can not find. You need to quote the content in with pipes in them i.e. "arg3|arg4|arg5":

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

If you are curious you can check out bash pitfalls. If you are not doing a lot of shell programming you may not see these problems often but when you do it may take you a while to figure out what is going on so learning more about shell programming can be helpful in the long term. I remember hitting number 3 and it took me a while to find a good solution the first time.

Upvotes: 4

NPE
NPE

Reputation: 500167

The | character has a special meaning in bash: it creates a pipeline.

Your program only sees the following arguments:

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

The |arg4 syntax is interpreted by bash to mean that the (non-existent) arg4 command should be run, and that the standard output of ./foo should be piped into the standard input of arg4. The |arg5 ... is interpreted in the same manner.

To suppress this behaviour, run your program like so:

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

(note the quotes).

Upvotes: 7

Related Questions