임의 인수 처리 정보

임의 인수 처리 정보

로컬에서 실행할 때 제대로 작동하는 스크립트를 작성했습니다.

./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/shbash 또는 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

관련 정보