It's not "losing the backslash". There is no backslash. The backslash tells the shell that the space is literal. This is preserved in the fact that `ls` gets two arguments ("test a" and "test b") instead of four arguments ("test", "a", "test", and "b"). That is the backslash's sole entire purpose and once it has accomplished that it is gone. Outside of the history functionality, the shell never remembers _how_ you typed a value. Only what value you typed.
Alternative ways to run `ls test\ ?` include:
ls 'test '?
ls "test "?
ls $'test\x20'?
ls \t\e\s\t\ ?
and many more besides. In each of these cases, what the shell does once you press the return key is exactly the same. The line you typed is preserved in the shell history, but that's the only record of the manner in which you quoted the argument.
So if you want access to the specific way the command is typed, you use a normal function or script; by the time it's executed it's too late.You need to hook into the completion or editing (ZLE) functionality.
This is a difficult question to ask because
I don't know if my little problem IS a problem at all:
5 /aWorking/Zsh/Source/Wk 11 % ls test\ ?
'test a' 'test b'
... yer basic 'ls'. 'l' is my wrapper around 'ls', however as
'$@' is passed to my function, it loses the backslash before the
space, it becomes: > test ? <. Easy to cope with, I
just single quote:
5 /aWorking/Zsh/Source/Wk 11 % l ,v 'test\ ?'
0 [26-04-04--09:00] test a
0 [26-04-04--09:03] test b
... but my sense of symmetry has me wanting the args to look
identical. I can hack it by replacing '$@' like this in test
function 'll':
out=${@//\ /\\ }
... and using '$out' in place of '$@' and it works by doubling the
backslash:
5 /aWorking/Zsh/Source/Wk 11 % ll test\ ?
0 [26-04-04--09:00] test a
0 [26-04-04--09:03] test b
... but I'm wondering if there's a less hacky way of protecting
the backslash. ' ${(q)@}' comes close but it also backslashes the
question mark. Or should I use my little hack above, OR ... do I
need therapy? Which is to say, is this a problem at all? Should
I just happily add the single quotes? Should I even want to
'solve' this? Sorry, I know this is a rather strange post. I'd
be very happy to hear that this shouldn't bother me at all. In
practical terms it's hardly an issue. But one could wish for some
way of taking any argument(s) to a function and passing them along
from one function to the next 'intact', so that there's never the
need to reprocess them.