値に$文字が含まれている場合に変数に値を割り当てる方法

値に$文字が含まれている場合に変数に値を割り当てる方法

私の目標:ユーザーから入力を受け取り、あるサーバーから別のサーバーに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'、、、などの特殊文字を$使用することは意味がありません。!"\

関連情報