원격 sed가 파일을 변경하지 못했습니다.

원격 sed가 파일을 변경하지 못했습니다.

이전 문자열과 새 문자열을 정의하는 다음 스크립트가 있습니다. 원격 연결을 통해 sed를 사용하여 이전 것을 새 것으로 교체하고 싶습니다. sed를 제외한 모든 명령이 작동하는 것 같습니다. 나는 구두점을 조정하고 sed를 사용하여 슬래시 대신 파이프를 사용해 보았지만 소용이 없었습니다. 명령 프롬프트에서 sed 명령을 실행하면 작동하지만 스크립트 내에서는 작동하지 않습니다. 이에 대한 의견을 보내 주시면 감사하겠습니다.

#!/bin/ksh

OLD="command\[Check_Memory_OS_10038\]=/opt/tools/nagitem/libexec/check_mem.pl -w 80,10 -c 90,25";export OLD
NEW="command\[Check_Memory_OS_10038\]=/opt/tools/nagitem/libexec/check_mem_ng.sh -w 80 -c 90";export NEW
DEST1="/opt/tools/nagitem/libexec/"
DEST2="/opt/tools/nagitem/nrdp/clients/nrds/"

for x in `cat /home/joe/nagios/hostlist`
do
SSH_STATUS=$(ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $USER@$x "pwd" >/dev/null)
  if [[ $? = "0" ]];then
    scp -p /home/joe/nagios/check_mem_ng.sh $x:/tmp
    ssh -o "StrictHostKeyChecking no" $x "sudo /usr/localcw/bin/eksh -c '/bin/cp /tmp/check_mem_ng.sh $DEST1;chown nagitem:nagitem $DEST1/check_mem_ng.sh;cd $DEST2; /bin/sed -i -e 's/'$OLD'/'$NEW'/g' /opt/tools/nagitem/nrdp/clients/nrds/nrds.cfg '"
else
   echo "Cannot connect to $x" >> badhosts
fi
done

수신된 오류는 다음과 같습니다. /bin/sed: -e 표현식 #1, 문자 39: 's'에 대한 알 수 없는 옵션

답변1

이 코드 조각은 몇 군데에서 정밀 검사가 필요합니다.

  • $OLD$NEW백슬래시가 다운스트림으로 사용되는 경우 환경 변수 n의 초기화에서는 이중 이스케이프를 방지하기 위해 이스케이프를 사용하지 않습니다.
  • sed 대체 명령의 LHS를 안전하게 삽입할 수 있도록 $OLD var를 이스케이프하세요.
  • 마찬가지로 대체 명령의 RHS에 대해 $NEW var를 이스케이프합니다.
  • sed 명령은 큰따옴표의 전체 범위 내에서 작은따옴표 안에 작은따옴표를 사용하므로 이스케이프됩니다. 또한 새 또는 이전 var 값에서 작은따옴표를 이스케이프하도록 주의하세요.
#!/bin/ksh

OLD="command[Check_Memory_OS_10038]=/opt/tools/nagitem/libexec/check_mem.pl -w 80,10 -c 90,25";export OLD
NEW="command[Check_Memory_OS_10038]=/opt/tools/nagitem/libexec/check_mem_ng.sh -w 80 -c 90";export NEW
DEST1="/opt/tools/nagitem/libexec/"
DEST2="/opt/tools/nagitem/nrdp/clients/nrds/"

#--------------------
# escape variables
eOLD=$(printf '%s\n' "$OLD" | sed -e 's:[][\/^$.*]:\\&:g' -e "s:':&\\&&:g")
eNEW=$(printf '%s\n' "$NEW" | sed -e 's:[\/&]:\\&:g' -e "s:':&\\&&:g")
#--------------------

for x in `cat /home/joe/nagios/hostlist`
do
SSH_STATUS=$(ssh -n -o BatchMode=yes -o StrictHostKeyChecking=no $USER@$x "pwd" >/dev/null)
  if [[ $? = "0" ]];then
    scp -p /home/joe/nagios/check_mem_ng.sh $x:/tmp
    ssh -o "StrictHostKeyChecking no" $x "sudo /usr/localcw/bin/eksh -c '/bin/cp /tmp/check_mem_ng.sh $DEST1;chown nagitem:nagitem $DEST1/check_mem_ng.sh;cd $DEST2; /bin/sed -i -e '\\''s/$eOLD/$eNEW/g'\\'' /opt/tools/nagitem/nrdp/clients/nrds/nrds.cfg'"
else
   echo "Cannot connect to $x" >> badhosts
fi
done

답변2

eksh 매개변수는 작은따옴표로 묶습니다 '. 작은따옴표 내에서는 특수 문자를 확장할 수 없습니다. 따라서 $DEST변수와 다른 변수가 확장되지 않아 이상한 잔차가 남습니다.

관련 정보