3

I am looking for the quoting/splitting rules for a command passed to script -c command. The man pages just says

-c, --command command: Run the command rather than an interactive shell.

but I want to make sure "command" is properly escaped.

Barmar
  • 741,623
  • 53
  • 500
  • 612
antony
  • 2,877
  • 4
  • 31
  • 43
  • The command is simply run by the shell, normal quoting rules apply. – Barmar Jun 02 '14 at 21:05
  • But it's also processed by the shell you're typing into, so you need to observe its quoting rules. But there's nothing special imposed by script. It's just like `bash -c commmand`. – Barmar Jun 02 '14 at 21:06
  • what ever you can type on 1 cmd line can be used as a string target to `-c`. It has to be quoted so it is all one string. This is fine until you want to use one of the outer quoting chars inside, like `-c 'ls -l | awk '{print $9}''` Ooops. For this case you can use dbl-quotes on the outside, but then `$9` will be interpreted as a shell cmd-line arg, so you have to escape that, ie.e `-c '"ls -l| awk '{print \$9}'"` , etc, etc. As is, your question is too vague to respond any further. If you have specific case that isn't working then post it as a new question. Good luck. – shellter Jun 02 '14 at 21:29
  • No, actually that's good enough, I figured it out, thanks. – antony Jun 02 '14 at 23:03

1 Answers1

0

The COMMAND argument is just a regular string that is processed by the shell as if it were an excerpt of a file. We may think of -c COMMAND as being functionally equivalent of

printf '%s' COMMAND > /tmp/command_to_execute.sh
sh /tmp/command_to_execute.sh

The form -c COMMAND is however superior to the version relying of an auxiliary file because it avoids race conditions related to using an auxiliary file.

In the typical usage of the -c COMMAND option we pass COMMAND as a single-quoted string, as in this pseudo-code example:

sh -c '
  do_some_complicated_tests "$1" "$2";
  if something; then
    proceed_this_way "$1" "$2";
  else
    proceed_that_way "$1" "$2";
  fi' ARGV0 ARGV1 ARGV2

If command must contain single-quoted string, we can rely on printf to build the COMMAND string, but this can be tedious. An example of this technique is illustrated by the overcomplicated grep-like COMMAND defined here:

% AWKSCRIPT='$0 ~ expr {print($0)}'
% COMMAND=$(printf 'awk -v expr="$1" \047%s\047' "$AWKSCRIPT")
% sh -c "$COMMAND" print_matching 'tuning' < /usr/share/games/fortune/freebsd-tips
"man tuning" gives some tips how to tune performance of your FreeBSD system.

Recall that 047 is octal representation of the ASCII code for the single quote character.

As a side note, these constructions are quite command in Makefiles where they can replace shell functions.

Community
  • 1
  • 1
Michaël Le Barbier
  • 6,103
  • 5
  • 28
  • 57