diff --git a/expand/expand.go b/expand/expand.go index fe285a2e..121cbb63 100644 --- a/expand/expand.go +++ b/expand/expand.go @@ -509,7 +509,8 @@ func (cfg *Config) wordField(wps []syntax.WordPart, ql quoteLevel) ([]fieldPart, if b == '\\' && i+1 < len(s) { switch s[i+1] { case '"', '\\', '$', '`': // special chars - continue + i++ + b = s[i] // write the special char, skipping the backslash } } sb.WriteByte(b) diff --git a/interp/interp_test.go b/interp/interp_test.go index 6462145a..de7ca44c 100644 --- a/interp/interp_test.go +++ b/interp/interp_test.go @@ -401,6 +401,11 @@ var runTests = []runTest{ {`echo \\\\`, "\\\\\n"}, {`echo \`, "\n"}, + // escape characters in double quote literal + {`echo "\\"`, "\\\n"}, // special character is preserved + {`echo "\b"`, "\\b\n"}, // non-special character has both characters preserved + {`echo "\\\\"`, "\\\\\n"}, // sequential backslashes (escape characters repeated sequentially) + // vars {"foo_interp_missing=bar_interp_missing; echo $foo_interp_missing", "bar_interp_missing\n"}, {"foo_interp_missing=bar_interp_missing foo_interp_missing=etc; echo $foo_interp_missing", "etc\n"},