로컬에서 실행할 때 제대로 작동하는 스크립트를 작성했습니다.
./sysMole -time Aug 18 18
논쟁"-시간","팔월","18", 그리고"18"성공적으로 스크립트에 전달되었습니다.
이제 스크립트는 원격 시스템에서 실행되지만 로컬 시스템의 로컬 디렉터리에서 실행되도록 설계되었습니다. 예:
ssh root@remoteServer "bash -s" < /var/www/html/ops1/sysMole
이것도 훌륭하게 작동합니다. 그런데 위의 주장을 포함하려고 하면 문제가 발생합니다.(-시간 2018년 8월 18일), 예를 들어:
ssh root@remoteServer "bash -s" < /var/www/html/ops1/sysMole -time Aug 18 18
스크립트를 실행한 후 다음 오류가 발생합니다.
bash: cannot set terminal process group (-1): Invalid argument
bash: no job control in this shell
내가 뭘 잘못하고 있는지 말해주세요. 매우 실망스럽습니다.
답변1
귀하의 예는 매우 가깝습니다. 이와 같은 매개변수와 함께 사용하면 매우 잘 작동합니다.
예시 스크립트:
$ more ex.bash
#!/bin/bash
echo $1 $2
유효한 예:
$ ssh serverA "bash -s" < ./ex.bash "hi" "bye"
hi bye
그러나 다음 유형의 인수에서는 실패합니다.
$ ssh serverA "bash -s" < ./ex.bash "--time" "bye"
bash: --: invalid option
...
어떻게 되어가나요?
당신이 겪고 있는 문제는 매개변수에 있거나 -time
제 --time
예에서는 로 전환하는 것으로 해석되는 것입니다 bash -s
. bash
인수로 종료하여 나머지 명령줄 인수를 가져오면 이를 달랠 수 있습니다 --
.
이와 같이:
$ ssh root@remoteServer "bash -s" -- < /var/www/html/ops1/sysMole -time Aug 18 18
예
#1:
$ ssh serverA "bash -s" -- < ./ex.bash "-time" "bye"
-time bye
#2:
$ ssh serverA "bash -s" -- < ./ex.bash "--time" "bye"
--time bye
#삼:
$ ssh serverA "bash -s" -- < ./ex.bash --time "bye"
--time bye
#4:
$ ssh < ./ex.bash serverA "bash -s -- --time bye"
--time bye
노트:분명히 말하면 명령줄에 리디렉션이 나타날 때마다 차이가 없습니다. ssh
원격 셸은 어쨌든 해당 인수를 연결하여 호출되기 때문에 원격 셸에서 인용할 필요가 없는 한 인용은 큰 차이를 만들지 않습니다. 예를 들어#4:
$ ssh < ./ex.bash serverA "bash -s -- '<--time bye>' '<end>'"
<--time bye> <end>
답변2
임의 인수 처리 정보
실제로 단일 문자열만 사용하는 경우, 즉. -time Aug 18 18
, 그러면 간단히 하드코딩할 수 있으며 기존 답변을 통해 이를 적절하게 수행하는 방법을 알 수 있습니다. 반면, 알 수 없는 매개변수(예: 다른 시스템에 표시할 메시지 또는 최종 사용자가 해당 이름을 제어할 수 있는 생성된 파일 이름)를 전달해야 하는 경우에는 더욱 주의해야 합니다.
bash
~ ksh
와 함께/bin/sh
원격이 /bin/sh
bash 또는 ksh에 의해 제공되는 경우 신뢰할 수 없는 인수 목록을 사용하여 다음을 안전하게 수행할 수 있으므로 악의적인 이름(예: $(rm -rf $HOME).txt
)도 안전하게 인수로 전달될 수 있습니다.
runRemote() {
local args script
script=$1; shift
# generate eval-safe quoted version of current argument list
printf -v args '%q ' "$@"
# pass that through on the command line to bash -s
# note that $args is parsed remotely by /bin/sh, not by bash!
ssh user@remote-addr "bash -s -- $args" < "$script"
}
모든 POSIX와 호환 가능/bin/sh
printf %q
충분히 악의적인 인수 데이터(이스케이프된 문자열에 인쇄할 수 없는 문자가 있을 때 bash에서 사용되는 비 POSIX 호환 인용문을 활용하려고 시도)로부터 안전하려면 /bin/sh
기본 POSIX(예: dash
또는ash
runRemote() {
local script=$1; shift
local args
printf -v args '%q ' "$@"
ssh user@remote-addr "bash -s" <<EOF
# pass quoted arguments through for parsing by remote bash
set -- $args
# substitute literal script text into heredoc
$(< "$script")
EOF
}
사용법(위의 상황 중 하나에 적용 가능)
그런 다음 위에 제공된 함수를 호출할 수 있습니다.
# if your time should be three arguments
runRemote /var/www/html/ops1/sysMole -time Aug 18 18
...또는...
# if your time should be one string
runRemote /var/www/html/ops1/sysMole -time "Aug 18 18"
답변3
다음과 같이 명령을 따옴표로 묶습니다.
ssh myserver "date +\"Date: %Y%m%d %H:%M\";printf \"Uptime: \";uptime;printf \"uname: \";uname -a"
Date: 20200409 20:02
Uptime: 20:02:29 up 66 days, 55 min, 2 users, load average: 0.06, 0.05, 0.08
uname: Linux zltcmtn23aecc1rx7322 4.4.0-116-generic #140-Ubuntu SMP Mon Feb 12 21:23:04 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
Connection to 105.31.182.217 closed.
답변4
aa가 ls를 포함하는 로컬 파일이라고 가정합니다.
$ssh servername "cat | bash" < a.a
127.0.0.1을 원격 IP 주소로 변경하세요.
이 두 가지는 가짜 tty 할당에 대한 메시지를 제공하지만 작동합니다.
$ cat a.a | ssh 127.0.0.1
$ ssh 127.0.0.1 <a.a
또는
$ cat a.a | ssh 127.0.0.1 bash or
$ ssh 127.0.0.1 bash < a.a