On 07/06/2018 06:18 AM, Jerry Geis wrote:
/opt/libreoffice5.4/program/soffice.bin --headless --convert-to csv "/tmp/file 2.xlsx"
MSG="file 2" MSG="csv "$MSG"" echo $MSG /opt/libreoffice5.4/program/soffice.bin --headless --convert-to $MSG
I'd describe what you're trying to do as "using one shell variable to expand to two and only two arguments in a shell simple command." And, as others have told you, you can't do that. The reason why is that shell parsing isn't recursive.
When the shell expands a simple command, it first parses the command in to words or tokens. This step is influenced by quoting. So this command: soffice --convert-to csv "file 2" ...becomes these tokens: [ 'soffice', '--convert0-to', 'csv', 'file 2' ] Quote characters which influence token parsing are removed in this step. Variable substitution happens after token parsing. So, this command: soffice --convert-to csv $msg ...becomes these tokens: [ 'soffice', '--convert-to', '$msg' ] ...which become to these tokens after variable substitution: [ 'soffice', '--convert-to', 'csv', '"file', '2"'] And this is where shell grammar gets a little confusing, because the shell doesn't parse the variable expansion according to the token rules, but it does perform "field splitting" on an unquoted variable, and that kind of looks like the same thing. It's not. You can't influence the expansion of the variable through quoting in its content, nor can you embed variable names or other substitutions.
This stuff is detailed here:
http://pubs.opengroup.org/onlinepubs/7908799/xcu/chap2.html
The easy solution is to use multiple variables. The slightly more complex solution is to use an array (which is supported by bash, but not POSIX shell, so it's not referenced in the above document). The really ugly solution is to use "eval":
msg="csv "file 2"" eval "soffice --convert-to $msg"
Don't use eval in any language, if you can avoid it. In non-trivial uses, it becomes difficult to predict all possible expansions, and can create variable injection attacks.