I have a function posix
that I use in the Git bash shell on Windows to transform DOS-style paths to normal Unix-style paths. Since DOS-style paths use a backslash as separator, I have to quote the path argument to prevent the backslashes as being used by the shell to denote the next character as a literal. Is there any way to get the uninterpreted argument from inside my function, so that I don't need to quote it?
Here is my function, if it helps:
function posix() {
echo $1 | sed -e 's|\\|/|g' | sed -re 's|^(.)\:|/\L\1|'
}
(By the way, I welcome any comments with tips for improving the function in other ways unrelated to solving the quoting/shell-interpretation problem.)
Best Answer
The uninterpreted shell arguments are
$1
,$2
, etc. You need to put their expansion in double quotes in most contexts, to avoid the value of the parameter being expanded further."$@"
gives you the list of all parameters.For example, if you want to pass an argument of the shell script to your function, call it like this:
The double quotes are necessary. If you write
posix $1
, then what you're passing is not the value of the first parameter but the result of performing word splitting and globbing on the value of the first parameter. You will need to use proper quoting when calling the script, too. For example, if you write this in bash:then the actual, uninterpreted arguments to
myscript
will bec:path
,with
andspacessomefile
. So don't do this.Your
posix
function is wrong, again because it lacks double quotes around$1
. Always put double quotes around variable and command substitutions:"$foo"
,"$(foo)"
. It's easier to remember this rule than the exceptions where you don't actually need the quotes.echo
does its own processing in some cases, and calling external processes is slow (especially on Windows). You can do the whole processing inside bash.The zsh feature that jw013 alluded to doesn't do what you seem to think it does. You can put
noglob
in front of a command, and zsh does not perform globbing (i.e. filename generation, i.e. expansion of wildcards) on the arguments. For example, in zsh, if you writenoglob locate *foo*bar*
, thenlocate
is called with the argument*foo*bar*
. You'd typically hide thenoglob
builtin behind an alias. This feature is irrelevant for what you're trying to do.