매개변수 주위에 큰따옴표가 있는 형식의 로그 파일에 매개변수를 에코합니다.

매개변수 주위에 큰따옴표가 있는 형식의 로그 파일에 매개변수를 에코합니다.

우분투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"

관련 정보