将参数回显到格式为参数周围用双引号括起来的日志文件

将参数回显到格式为参数周围用双引号括起来的日志文件

乌班图16.04

我想将原始命令回显到日志文件。我的日志文件应该如下所示:

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

在满足拼写检查的同时完成此任务的最简单方法是什么?

#!/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

我不能选择第一行,因为我必须提前知道参数。

这是我运行上述命令时控制台所说的内容。

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"

答案1

您可以获得shell 引用的输出使用@Q扩展修饰符在 Bash 4.4 及更高版本中:

$ 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'

它使用单引号,而不是双引号,但它确保输出作为输入返回到 shell 中时有效,从而执行您所期望的操作。下面是一个重要的示例,但如果您的日志格式需要双引号,则没有帮助。

有点令人困惑的是,在连续字符中${@@Q}使用@表示两种不同的含义:第一个@表示参数数组,而第二个则引入一个修饰符来转换数组扩展的输出。修饰符Q导致输出被引用。$@与 不同,单独展开到每个元素$*,但它大概在这种情况下并不重要(尽管如果您的实际代码更复杂,则可能会如此)。


@Q、 、 、printf %q、 使用单引号,因为它们会抑制其他 shell 扩展 - 如果其中一个参数包含$`\"、 或!,则任何带有双引号的内容都会受到怀疑。@Q确保每一个术语被引用,即使它不一定需要它(而不printf需要)。空格的处理仍然正确。

$ 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'

你可以将该命令复制回来,无论输入多么反常,它都会起作用。

答案2

这似乎有效:

#!/bin/bash

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

测试用:

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

它不会用“引用”,因为(正如您从测试中看到的)“可以是输入的一部分。它使用 \ 代替。 GNU Parallel 中的 shell 引用功能经过了广泛的测试,所以如果你能给它提供将被错误引用的输入,我会感到惊讶。

答案3

使用简单的循环

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

例如

./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"

会破坏它的一件事是如果输入"中有一个

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

相关内容