rpm --define unexpectedly deletes backslashes from the argument: $ rpm --define="foobar 'an'" --showrc | fgrep foobar -8: foobar 'an' $ rpm --define="foobar \'\a\n\'" --showrc | fgrep foobar -8: foobar 'an' $ echo rpm --define="foobar \'\a\n\'" --showrc rpm --define=foobar \'\a\n\' --showrc $ rpm -q rpm rpm-4.13.0.1-alt1.x86_64 $ Is this documented? What's the use of it? To be more precise, it deletes a backslash and skips the next character: $ echo rpm --define='foobar \\\\\a' --showrc rpm --define=foobar \\\\\a --showrc $ rpm --define='foobar \\\\\a' --showrc | fgrep foobar -8: foobar \\a $ The only use I can think of is escaping a space at the beginning: $ rpm --define='foobar \ a' --showrc | fgrep foobar -8: foobar a $ rpm --define='foobar a' --showrc | fgrep foobar -8: foobar a $
The use of the backslashes in rpm turns out to be there for multiline values. In spec: %define foo a\ b or in command line: $ rpm --define 'foo a\ > b' --eval '%foo' a b $ This means we need to escape backslashes and perhaps need a special tool to do this (in scripts). printf %q is an incorrect "overkill" because it does also other kinds of escaping/quoting. Perhaps something like: rpm --define "foo $(sed -e 's:\:\\:g' <<<"$VALUE")" $ VALUE='a\b' $ echo "$VALUE" a\b $ rpm --define "foo $(sed -e 's:\\:\\\\:g' <<<"$VALUE")" --eval '%foo' a\b $