우분투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
당신은 얻을 수 있습니다쉘에서 인용다음을 사용하여 출력@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'
큰따옴표가 아닌 작은따옴표를 사용하지만 셸에 입력으로 반환될 때 출력이 유효한지 확인하여 예상한 대로 수행됩니다. 다음은 중요한 예이지만 로그 형식에 큰따옴표가 필요한 경우에는 도움이 되지 않습니다.
다소 혼란스럽게도 연속 문자에 ${@@Q}
사용하는 @
것은 두 가지 다른 의미를 갖습니다. 첫 번째는 @
매개변수 배열을 나타내고 두 번째는 배열 확장의 출력을 변환하는 수정자를 도입합니다. 수정자는 Q
출력이 인용되도록 합니다. $@
달리 각 요소를 개별적으로 확장 $*
하지만아마도이 경우에는 중요하지 않습니다(실제 코드가 더 복잡한 경우에는 중요할 수도 있음).
@Q
, , , printf %q
, 작은 따옴표는 다른 쉘 확장을 억제하기 때문에 사용합니다. 인수 중 하나에 $
, `
, \
, "
또는 가 포함되어 있으면 !
큰 따옴표가 있는 모든 항목이 의심됩니다. @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의 쉘 인용 기능은 광범위하게 테스트되었으므로 제공할 수 있는 경우 제공하십시오. 잘못 인용되어 놀랄 것입니다.
답변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"