乌班图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"