tags:

views:

240

answers:

4

Let's say I have a C program, and I run it from bash:

$ ./a.out 123 *

The program would output all the command line arguments, but it will show these instead:

Argument 1: 123 Argument 2: a.out

What can I do in my program to fix this?

+5  A: 

You can quote it in the shell

./a.out 123 '*'

There is nothing you can do in your program, because the * expansion is done by the shell (in contrast to Windows, where it's done by the program).

Matthew Flaschen
Exactly. The shell expands metacharacters BEFORE invoking the executable, so your program doesnt know that the user typed an asterisk. This is good standard Unix behaviour, and you dont want to 'fix' it. If you dont want the shell to expand metacharacters, you escape them with \ or put args inside single quotes.
leonbloy
+7  A: 

The shell is replacing the asterisk with the name of each file in the directory.

To pass a literal asterisk, you should be able to escape it:

$ ./a.out 123 \*
James McNellis
Right, I understand that that would work, but I was wondering if there is anything I could do in my C program without having to change the way I pass in arguments
Yz Chong
@Yz: I'm not a bash expert; my guess is that the answer is "not easily."
James McNellis
@James, I _am_ a bash expert; my answer is "no!" :-) +1 for the backslash solution - this is preferred IMNSHO since the quotes will prevent variable expansion. Backslashing a single character will not have that side effect.
paxdiablo
You can run `bash -f` to disable globbing/filename expansion altogether, although I'm not really sure this is what the OP wants.
spong
James is correct. You can't do anything about this in C because the shell will replace the `*` *before* it calls your program. The C program has no way of determining whether a wildcard was passed to the shell or (in this case) a manually-typed list of files. In order to get the pure `*` to your C program, you have to escape it (that is, tell the shell not to expand it like it normally would) using `\\*`.
bta
+4  A: 

This doesn't have anything to do with your program.

The * is a wildcard in Bash, it means "all files in the current directory". If you want to pass an asterisk as an argument to your program, you do it the same way you do it with every other program: you escape it with a backslash or quote it.

Jörg W Mittag
A: 

Another option is to use set -f to turn off expansion. compare:
echo *
vs
set -f
echo *

frankc