[CentOS] Bash question

Gordon Messmer gordon.messmer at gmail.com
Sat Jul 7 17:18:46 UTC 2018


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.



More information about the CentOS mailing list