当值中包含 $ 字符时如何为变量赋值

当值中包含 $ 字符时如何为变量赋值

我的目标:自动化从一台服务器到另一台服务器的 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. 我无法将 some$value 值分配给变量 SERVICE_PASS 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

因为您在期望脚本主体中使用双引号,所以您必须处理两个都shell变量扩展和expect(即Tcl)变量扩展。当expect运行时,shell变量已被扩展,因此expect会看到:

expect password: { send some$value\r }

所以现在,您需要处理 Tcl 变量。

可以添加更多引用:

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

但这不是必需的:我会将 Expect 脚本放在单引号中,并通过环境传递 shell 参数。这样,每个变量只会被替换一次:无论是在 shell 中还是在 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'; $!"、等特殊字符\在其中没有任何意义。

相关内容