값에 $ 문자가 포함된 경우 변수에 값을 할당하는 방법

값에 $ 문자가 포함된 경우 변수에 값을 할당하는 방법

내 목표: 사용자로부터 입력을 받아 한 서버에서 다른 서버로 scp를 자동화합니다. 과제: 대상에 액세스할 수 있는 사용자가 소스 서버에도 액세스할 수 있기 때문에 서버 간에 SSH 인증 호스트 동등성을 설정할 수 없습니다. 따라서 필요합니다. 프롬프트가 표시될 때 비밀번호를 제공하고 scp를 실행하는 기존 방식을 설정합니다.

이게 내 코드야

L_SRC_SID=source
L_SID=target
MOUNT_POINT=app07
SERVICE_PASS=some$value
APP_SERVER_1=hostname
SRC_MOUNT_POINT=app01

#And now transfer the file over
/usr/bin/expect -c "
   set timeout 1
   cd /$MOUNT_POINT/$L_SID/apps
   spawn scp -pr * apps@$APP_SERVER_1:/$SRC_MOUNT_POINT/$L_SRC_SID/apps .
   expect yes/no { send yes\r ; exp_continue }
   expect password: { send $SERVICE_PASS\r }
   expect 100%
   sleep 1
   exit
"

exit

과제: 1. SERVICE_PASS 변수에 some$value를 할당할 수 없습니다. 2. 비밀번호에 $ 문자가 포함된 변수를 사용하여 Expect send 스크립트가 작동하도록 만드는 방법. 다음 오류로 인해 실패합니다.

password: can't read "value": no such variable

도움을 주시면 감사하겠습니다.

제안한 대로 코드를 변경했지만 여전히 같은 오류가 발생합니다.

L_SRC_SID=source
L_SID=target
MOUNT_POINT=app07
SERVICE_PASS='some$value'
APP_SERVER_1=hostname
SRC_MOUNT_POINT=app01

#And now transfer the file over
/usr/bin/expect -c "
   set timeout 1
   cd /$MOUNT_POINT/$L_SID/apps
   spawn scp -pr * apps@$APP_SERVER_1:/$SRC_MOUNT_POINT/$L_SRC_SID/apps .
   expect yes/no { send yes\r ; exp_continue }
   expect password: { send $SERVICE_PASS\r }
   expect 100%
   sleep 1
   exit
"

exit

이것은 완전한 오류입니다.

password: can't read "value": no such variable
    while executing
"send some$value\r "
    invoked from within
"expect password: { send some$value\r }"

답변1

이 경우 값을 작은따옴표로 묶어야 합니다.

'some$value'

큰따옴표는 ""파일 이름 확장을 억제하지만 변수 확장은 억제하지 않습니다.

$ value="some$value"
$ echo $value
 some

작은따옴표는 ''파일 이름과 변수 확장을 억제합니다.

$ value='some$value'
$ echo $value
 some$value

백틱을 사용 ``하면 변수 확장이 가능합니다.

$ value=`some$value`
$ echo $value`

$

$따라서 , , 등의 문자 확장을 억제 !하고 "작은 / 따옴표를 사용하세요!

답변2

예상되는 스크립트 본문에 큰따옴표를 사용하고 있기 때문에 다음을 처리해야 합니다.둘 다쉘 변수 확장 및 예상(예: Tcl) 변수 확장. 예상이 실행되면 쉘 변수가 확장되었으므로 예상은 다음을 참조합니다.

expect password: { send some$value\r }

이제 Tcl 변수를 처리해야 합니다.

할 수 있다더 많은 인용문을 추가하세요:

/usr/bin/expect -c "
    ...
    expect password: { send {$SERVICE_PASS}; send \r }

그러나 이것이 필수는 아닙니다. Expect 스크립트를 작은따옴표로 묶고 환경을 통해 셸 인수를 전달합니다. 이런 방식으로 각 변수는 셸이나 Expect에서 한 번만 대체되므로 놀랄 일이 없습니다.

export L_SRC_SID L_SID MOUNT_POINT SERVICE_PASS APP_SERVER_1 SRC_MOUNT_POINT

/usr/bin/expect -c '  # <- single quote
    set timeout -1
    cd /$env(MOUNT_POINT)/$env(L_SID)/apps
    spawn scp -pr * apps@$env(APP_SERVER_1):/$env(SRC_MOUNT_POINT)/$env(L_SRC_SID)/apps .
    expect {
        yes/no    { send yes\r ; exp_continue }
        password: { send $env(SERVICE_PASS)\r }
    }
    expect eof
'

일반적으로 sleepinexpect를 사용한다는 것은 오류가 시간 초과되거나 잘못된 것을 기대한다는 것을 의미합니다. 나는 변했어.

답변3

'strong quotes', , 등의 특수 문자를 $사용 하는 것은 의미가 없습니다.!"\

관련 정보