3

Ubuntu 16.04

I am wanting to echo the original command to a log file. My log file should look something like this:

Mon 04/16/18 04-24-pm - Executing command: sudo /home/editini.sh "one" "two" "three" "four" "five" "six"

What would be the easiest way to accomplish this while satisfying spellcheck at the same time.

#!/bin/bash


hello="${1}"
my="$2"
friend="$3"
are="$4"
you="$5"
safe="$6"
timeStamp="$(date '+%a %D %m-%S-%P')"

rm -rf report*; touch report.txt;
{
   echo "$timeStamp - Executing command: sudo /home/editini.sh \"$hello\" \"$my\" \"$friend\" \"$are\" \"$you\" \"$safe\""
   echo ""
   echo "$timeStamp" -  Executing command: sudo /home/editini.sh "$*"
   echo "";
   echo "$timeStamp" -  Executing command: sudo /home/editini.sh \""$*"\"
   echo "";
} > report.txt
cat report.txt

I can't go with the first line because I would have to know the arguments ahead of time.

This is what console says when I run the above commands.

root@me /home/scripts/vent-commands # sh one.sh one two three four five six
Mon 04/16/18 04-05-pm - Executing command: sudo /home/editini.sh "one" "two" "three" "four" "five" "six"

Mon 04/16/18 04-05-pm - Executing command: sudo /home/editini.sh one two three four five six

Mon 04/16/18 04-05-pm - Executing command: sudo /home/editini.sh "one two three four five six"
  • What is the expected output? – Nasir Riley Apr 16 '18 at 22:55
  • Do you want specifically double quotes around the value, or a shell-quoted representation of it (that you could copy and paste back in)? – Michael Homer Apr 16 '18 at 23:09
2

You can get a shell-quoted output using the @Q expansion modifier in Bash 4.4 and later:

$ echo "$timeStamp" -  Executing command: sudo /home/editini.sh "${@@Q}"
Mon 04/16/18 04-05-pm - Executing command: sudo /home/editini.sh 'one' 'two' 'three' 'four' 'five' 'six'

It uses single quotes, rather than double, but it ensures that the output is valid as input back into the shell that does what you'd expect. An example of where that matters is below, but if your log format requires double quotes it's not helpful.

Somewhat confusingly, ${@@Q} uses the @ for two different meanings in consecutive characters: the first @ represents the arguments array, while the second introduces a modifier that transforms the output of the array's expansion. The Q modifier causes the output to be quoted. $@ expands to each element individually turn, unlike $*, but it probably doesn't matter in this case (though it might if your real code is more complex).


@Q, and printf %q, use single quotes because they inhibit other shell expansions - if one of the arguments has a $, `, \, ", or ! in it, anything with double quotes will be suspect. @Q ensures that every term is quoted, even if it doesn't necessarily require it (while printf doesn't). Spaces are still handled correctly.

$ set -- 'o$ne' "t w o" th\`ree fo\\ur five\! s\"i\'x
$ echo "$timeStamp" -  Executing command: sudo /home/editini.sh "${@@Q}"
Mon 04/16/18 04-05-pm - Executing command: sudo /home/editini.sh 'o$ne' 't w o' 'th`ree' 'fo\ur' 'five!' 's"i'\''x'

You could copy that command back in and it would just work, no matter how perverse the input was.

  • line 7: ${@@Q}: bad substitution is what I receive when I run it. – needtoknow Apr 17 '18 at 0:06
  • 1
    The expansion modifiers are a Bash 4.3 or 4.4 feature; what version are you using? – Michael Homer Apr 17 '18 at 0:09
  • bash --version GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu) Copyright (C) 2013 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <gnu.org/licenses/gpl.html> – needtoknow Apr 17 '18 at 1:29
  • Yes, looks like it was new in 4.4. – Michael Homer Apr 17 '18 at 1:32
  • I installed bash 4.4. It still didn't work. I rebooted and presto. Tue 04/24/18 04-02-pm - Executing command: hello.sh 'Hello' 'my' 'friend' 'are' 'you' 'safe' . -- Hat off to you mate! – needtoknow Apr 24 '18 at 20:17
0

This seems to work:

#!/bin/bash

a=$(parallel --shellquote ::: "$@")
echo "$timeStamp" -  Executing command: sudo /home/editini.sh $a

Tested with:

mylog '"I  want  a  2"x4"", said the 3 * captain"' to his friend

It will not quote with ", because (as you can see from the test) " can be part of the input. It uses \ instead. The shell quoting function in GNU Parallel is tested extensively, so I will be surprised if you can give it input that will be quoted wrongly.

0

Use a simple loop

{
   echo -n "$timeStamp - Executing command: sudo /home/editini.sh"
   for a in "$@"
   do
     echo -n " \"$a\""
   done
   echo
} > report.txt

e.g

./x one two "three and four together" five    
Mon 04/16/18 04-46-pm - Executing command: sudo /home/editini.sh "one" "two" "three and four together" "five"

The one thing that will break it is if the input has a " in it

% ./x one "two\"three" four
Mon 04/16/18 04-21-pm - Executing command: sudo /home/editini.sh "one" "two"three" "four"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.