중첩된 참조 악몽: 원격 호스트에서 이메일 보내기

중첩된 참조 악몽: 원격 호스트에서 이메일 보내기

SSH를 통해 액세스하는 원격 호스트에서 첨부 파일이 포함된 이메일을 (내 터미널에서) 보내야 합니다. 원격으로 작업을 수행하려면 다음을 사용한다는 것을 이미 알고 있습니다.

ssh -p myport [email protected] "doSomething"

또한 첨부 파일이 포함된 이메일을 보내려면 필요한 것도 알고 있습니다.

echo "Mail content" | mailx -s "Mail title" -a attachment.txt -S from="myname@gmail" destname@gmail

따라서 이 둘의 간단한 조합은 doSomething첫 번째 행을 두 번째 행의 전체 내용으로 바꾸는 것입니다. 물론 이것은 끔찍한 중첩된 큰따옴표 때문에 작동하지 않습니다. 이 작업을 어떻게 수행합니까(가능한 경우 깔끔하게)? 도움을 주시면 감사하겠습니다.

답변1

간단한 경우 작은따옴표를 사용하여 로컬 셸의 명령을 보호하거나 큰따옴표를 \".

echo "Mail content" | ssh -p myport [email protected] 'mailx -s "Mail title" -a attachment.txt -S from="myname@gmail" destname@gmail'
# or
echo "Mail content" | ssh -p myport [email protected] "mailx -s \"Mail title\" -a attachment.txt -S from=\"myname@gmail\" destname@gmail"

더 복잡한 경우 가장 간단한 방법은 구분 기호를 사용하여 변수를 설정하는 것입니다.

read -r -d '' mailcmd <<'CMD'
echo "quotin'" 'this would be a "nightmare" indeed.' | mailx -s "Anthony's Email" -a attachment.txt -S from="myname@gmail" destname@gmail
CMD
ssh -p myport [email protected] "$mailcmd"

적어도 bash에서는 쉘에 변수를 참조하도록 요청할 수 있습니다. 이는 더 성가신 작업(예: 체인 2 호출)을 수행해야 할 ssh때 도움이 될 수 있습니다 .

$ printf '%q\n' "$mailcmd"
echo\ \"quotin\'\"\ \'this\ would\ be\ a\ \"nightmare\"\ indeed.\'\ \|\ mailx\ -s\ \"Anthony\'s\ Email\"\ -a\ attachment.txt\ -S\ from=\"myname@gmail\"\ destname@gmail

보시다시피 자동 인용은 최소 백슬래시에 최적화되어 있지 않습니다.

지역 변수 포함

명령에 변수를 사용해야 하는 경우 ssh는 유효한 특수 사례를 제공합니다. ssh는 SendEnv옵션(클라이언트) 및 옵션(서버)에 AcceptEnv지정된 환경 변수를 전달할 수 있습니다. 환경 변수를 전달하면 원격측 셸은 해당 변수를 정상적으로 확장합니다(여기 문서에 "$varname"이 있으면 원격측 셸도 해당 변수를 확장합니다).

그 외에 가장 쉬운 방법은 구분된 문서에서 따옴표를 생략하는 것입니다. 이렇게 하면 확장이 발생합니다(비록 $원하지 않는 곳에서 이스케이프해야 함을 의미하지만).

$ var1="hello world"
$ read -r -d '' mailcmd <<CMD
echo "$var1" "\$var1"
CMD
$ echo "$mailcmd"
echo "hello world" "$var1"

확장을 닫는 이와 같은 닫는 태그를 인용하는 CMD대신 ; 을 어떻게 사용했는지 주목하세요 . 'CMD'따라서 이를 참조하지 않음으로써 확장을 얻게 됩니다. 예상대로 "$var1"확장되지만 hello world앞에 백슬래시를 넣으면 확장을 피할 수 있습니다. 백틱 및 확장을 포함하여 모든 확장이 활성화됩니다 $(…). 또한 var1은 단지 대체됩니다. 쉘은 여기서 이스케이프를 수행하지 않으므로 var1에 큰따옴표 등이 포함되어 있으면 이 방법이 작동하지 않습니다. %q를 사용할 수 있는 곳은 다음과 같습니다.

$ var1='hello "world"'
$ read -r -d '' mailcmd <<CMD
echo $(printf '%q' "$var1") "\$var1"
CMD
$ echo "$mailcmd"
echo hello\ \"world\" "$var1"

경고의 말씀:전달한 데이터가 공격자에 의해 손상될 수 있는 경우 다음을 수행해야 합니다.매우주의 깊은. 이스케이프 시 약간의 오류(또는 관련된 모든 셸 간에 이스케이프해야 하는 항목에 대한 다른 정의)는 임의의 코드 실행 결함이 될 수 있습니다.필요한 모든 이스케이프가 존재하거나 올바른지 확인하는 것보다 더 강력한 데이터 전달 시스템을 구축하는 것이 더 쉬운 경우가 많습니다.많은보안 취약점으로 인해 계속해서 오류가 발생합니다.

관련 정보