Issue
I'm recreating Bash in C, and I'm trying to figure out what argument does the command get with empty quotes. I'm executing commands with execve
.
echo 123''456
just prints out 123456
, but if you put
char *echo_args[] = {"echo", "123", "", "456", NULL};
execve("/bin/echo", echo_args, NULL);
the output is 123 456
with space between, so I figured out that the only way to remove that space is by not putting the empty string argument in execve
; but then if you do grep ''
, grep clearly gets some argument because it's not acting same as if it was just grep
, so what I'm asking is why does echo
not get an empty string as its argument and grep
does?
Solution
In the shell command echo 123''456
, the ''
s don't turn into anything; they're completely removed during parsing and not passed to echo
at all.
This is because the shell parses quotes character-by-character; 123''456
concatenates the unquoted string 123
, a single-quoted empty string, and an unquoted string 456
into a single argument.
By contrast, in grep ''
, the ''
is separated by spaces from any other arguments, preventing that empty string from being concatenated into (and thus subsumed by) anything else.
To execute echo
from bash the same way your C code does, with three separate arguments beyond argv[0]
, you can run:
enable -n echo # turn off bash-builtin echo so we use the one from /bin
echo 123 '' 456
Notice the spaces between ''
and the surrounding arguments; these spaces are shell syntax, causing the empty string to be its own argument rather than being appended to something non-empty and thus disappearing.
Answered By - Charles Duffy Answer Checked By - Timothy Miller (WPSolving Admin)