While other answers may be correct in stating that you cannot receive "uninterpreted" shell input via the means they mention, they are wrong in categorically denying it as a possibility. You can certainly receive it before the shell interprets it if you instruct the shell not to interpret it. The humble POSIX heredoc
makes this very simply possible:
% sed -e 's@\\@/@g' -e 's@\(.\):\(.*\)@/drive/\1\2@' <<'_EOF_'
> c:\some\stupid\windows\place
> _EOF_
/drive/c/some/stupid/windows/place
EDIT1:
In order to pass such a string to a shell function as a shell argument you're going to need to store it in a shell variable. Generally you cannot simply var=<<'HEREDOC'
unfortunately, but POSIX does specify the -r
argument to the read
builtin:
% man read
POSIX PROGRAMMER'S MANUAL
...
By default, unless the -r option is specified, backslash ( '\' ) shall act as an escape character, as described in Escape Character (Backslash) . If standard input is a terminal device and the invoking shell is interactive, read shall prompt for a continuation line when:
The shell reads an input line ending with a backslash, unless the -r option is specified.
A here-document is not terminated after a new line is entered.
When combined, read
and the heredoc
make this a trivial and portable matter as well, though it may not feel very intuitive at first:
% _stupid_mspath_fix() {
> sed -e 's@\\@/@g' -e 's@\(.\):\(.*\)@/drive/\1\2@' <<_EOF_
>> ${1}
>> _EOF_
> }
% read -r _stupid_mspath_arg <<'_EOF_'
> c:\some\stupid\windows\place
> _EOF_
% _stupid_mspath_fix ${_stupid_mspath_arg}
/drive/c/some/stupid/windows/place
EDIT2:
Probably you noticed the difference between the two heredocs
in the second example. The heredoc
_EOF_
terminator within the function is unquoted, while the one fed to read
is quoted with single quotes. In this way the shell is instructed to perform expansion on the heredoc
with an unquoted terminator, but not to do so when its terminator is quoted. It doesn't break when expanding the unquoted heredoc
in the function because the value of the variable it expands is already set as a quoted string and it doesn't parse it twice.
Probably what you want to do involves piping your Windows path from the output of one command into the input of another dynamically. Command substitution within a heredoc
makes this possible:
% _stupid_mspath_fix() {
> sed -e 's@\\@/@g' -e 's@\(.\):\(.*\)@/drive/\1\2@' <<_EOF_
>> ${1}
>> _EOF_
> }
% read -r _stupid_mspath_arg <<'_EOF_'
> c:\some\stupid\windows\place
> _EOF_
% _stupid_mspath_fix ${_stupid_mspath_arg}
/drive/c/some/stupid/windows/place
% read -r _second_stupid_mspath_arg <<_EOF_
> $(printf ${_stupid_mspath_arg})
> _EOF_
% _stupid_mspath_fix ${_second_stupid_mspath_arg}
/drive/c/some/stupid/windows/place
So basically if you can reliably output the backslashes from some application (I used printf
above), then running that command within $(...)
and enclosing that within an unquoted heredoc
passed to another application that can reliably accept the backslashes as input (such as read
and sed
above) will bypass the shell's parsing of your backslashes altogether. Whether or not the applications can handle the backslashes as input/output is something you'll have to find out for yourself.
Not strictly relevant to the question:
In Gilles's answer he recommends the ${var/search/replace}
parameter expansion form, which, though cool, is not POSIX. It is definitely a bashism. It wouldn't matter to me, but in his edits he retained the posix ()
function name, and that may be misleading to some.
On that note, the original post's posix ()
function makes use of the very convenient extended regex sed -r
argument, but that is also, unfortunately, not POSIX. POSIX does not specify an extended regex argument for sed
, and its use is therefore possibly unreliable.
My account at stack overflow is only a few only days old as well, but I've posted a few answers there dealing specifically with POSIX parameter expansion which you can find linked to from my profile page, and in which I include quotes from the POSIX guidelines and links thereto. You will also find a few in which I demonstrate other uses of the heredoc
, such as reading an entire shell script into a shell variable, parsing and manipulating it programmatically, then finally running its new version all done from within another script or shell function. Just saying.
zsh
has a way to declare that certain functions should not have their arguments expanded, butzsh
is a very atypical and nonstandard shell, and you won't find most of its features anywhere else. – jw013 Sep 28 '12 at 16:34WinMain
function gets it as one argument! Now Microsoft's Visual C run-time library does it in some particular way to produce arguments for the standard Cmain
. It's hacky, and incompatible with other schemes on the same platform. Sure, for a simpleA B C
command line, there is agreement, but once you bring quotes into the picture, and whatnot, all bets are off. – Kaz Nov 23 '13 at 06:48