How do quotation mark in arguments to commands work?

103 views
Skip to first unread message

Ed

unread,
Jun 5, 2014, 1:02:42 PM6/5/14
to help-c...@googlegroups.com
Sometimes, out of convenience more than necessity, I use a commands promise with inline arguments.  When the argument being passed to the module contains a quotation mark, we can just alternate between single and double quotes to get the argument passed to the command.

For example:

body common control
{
  bundlesequence
=> { "quote_test" };
}

bundle agent quote_test
{
  commands
:
     
# This prints
     
# I am a single quote: '
     
"/bin/echo \"I am a single quote: '\"";


     
# This prints
     
# I am a double quote: "
     
'/bin/echo \'I am a double quote: "\'';
}


Today I tried to pass an argument containing both double and single quotation marks, but couldn't get it to work.  It seems that if the argument is enclosed in double quotes, there is no way to sneak a double quote within, and if the argument is enclosed in single quotes, there is no way to sneak a single quote within:

body common control
{
 bundlesequence
=> { "quote_test" };
}

bundle agent quote_test
{
 commands
:
 
# This prints
 
# I am a double quote: \
 
'/bin/echo "I am a double quote: \\\""';


 
# This prints
 
# I am a single quote: \
 
"/bin/echo 'I am a single quote: \\\''";
}



I think this behaviour is fine and good for security reasons, so I proceeded to write a proper module that reads from a file.

Just out of curiosity, and to prevent accidents, can anyone please confirm this for me?  I would like to be sure:  Is there any way a command with an argument enclosed in double quotes can receive a double quote in that argument?  Or a command with an argument enclosed in single quotes can receive a single quote in that argument?

I'm mainly interested in a Linux environment using noshell.  Thanks for any insights.

Ed

Neil Watson

unread,
Jun 5, 2014, 1:27:13 PM6/5/14
to help-c...@googlegroups.com
Confirm, something odd happens.

neil@ettin ~/.cfagent/inputs $ cf-agent -Kf ./quotes.cf
2014-06-05T13:25:18-0400 notice: /default/main/methods/'any'/default/test/commands/'/bin/echo "double quotes: "" "'[0]: Q: ".../bin/echo "doub": double quotes:

neil@ettin ~/.cfagent/inputs $ !cat
cat quotes.cf
body common control
{
bundlesequence => {
"main",
};
}

bundle agent main
{
methods:

"any" usebundle => test;
}

bundle agent test
{
commands:
'/bin/echo "double quotes: \"\" "';
}
neil@ettin ~/.cfagent/inputs $ /bin/echo "double quotes: \"\" "
double quotes: ""


--
Neil H Watson
Compliance reporting with CFEngine Community http://evolvethinking.com/products/delta-reporting/
Simplify CFEngine with EFL http://evolvethinking.com/evolve-thinkings-free-cfengine-library/
VIM and Cfengine https://github.com/neilhwatson/vim_cf3
CFEngine support and training from Evovle Thinking, http://evolvethinking.com

Ted Zlatanov

unread,
Jun 6, 2014, 7:43:15 AM6/6/14
to help-c...@googlegroups.com
On Thu, 5 Jun 2014 10:02:42 -0700 (PDT) Ed <ed.6...@gmail.com> wrote:

E> Is there any way a command with an argument enclosed in double quotes
E> can receive a double quote in that argument? Or a command with an
E> argument enclosed in single quotes can receive a single quote in that
E> argument?

E> I'm mainly interested in a Linux environment using noshell. Thanks for any
E> insights.

If noshell is a requirement, I found no workaround. With shell:

#+begin_src cfengine3
body common control
{
bundlesequence => { "quote_test" };
inputs => { "$(sys.libdir)/stdlib.cf" };
}

bundle agent quote_test
{
commands:
'/bin/echo "in_shell double quote: \\" "' contain => in_shell;
"/bin/echo \"in_shell single quote \' \"" contain => in_shell;

'/bin/echo double quote: \\" ';
"/bin/echo single quote \\' ";
}

#+end_src

output:

#+begin_src text
2014-06-06T07:42:19-0400 notice: /default/quote_test/commands/'/bin/echo "in_shell double quote: \" "'[0]: Q: ".../bin/echo "in_s": in_shell double quote: "
2014-06-06T07:42:19-0400 notice: /default/quote_test/commands/'/bin/echo "in_shell single quote ' "'[0]: Q: ".../bin/echo "in_s": in_shell single quote '

2014-06-06T07:42:19-0400 notice: /default/quote_test/commands/'/bin/echo double quote: \" '[0]: Q: ".../bin/echo doubl": double quote: \"
2014-06-06T07:42:19-0400 notice: /default/quote_test/commands/'/bin/echo single quote \' '[0]: Q: ".../bin/echo singl": single quote \'
#+end_src

HTH
Ted

Ed

unread,
Jun 6, 2014, 10:04:49 AM6/6/14
to help-c...@googlegroups.com
Neil and Ted,

Thank you for the time you took to confirm.  I think it's safe to presume that you just cannot sneak a matching quote inside an argument to a command with noshell.

Have a good one,

Ed

Neil Watson

unread,
Jun 6, 2014, 10:08:57 AM6/6/14
to help-c...@googlegroups.com
On Fri, Jun 06, 2014 at 07:04:48AM -0700, Ed wrote:
> Thank you for the time you took to confirm.  I think it's safe to
> presume that you just cannot sneak a matching quote inside an argument
> to a command with noshell.
> Have a good one,

I was teaching a CFEngine intro course this week. I have a slide about
CFEngine commands and the shell. I warn that the commands env is often
different than seen in the shell. This is another good example. Thanks
for bringing it up.
Reply all
Reply to author
Forward
0 new messages