LINUX.ORG.RU

Специальные символы в переменных (Expect)

 


0

2

Насущный вопрос, как передать содержимое переменной в Expect, если в переменной имеется символ $? Имеется ряд паролей, содержащих спец.символы, и при попытке передать их куда-то (например в пароль, для ssh) заканчиваются ошибкой. Например:


PWD="PaS\$word"
spawn ssh root@localhost
expect "*password:"
send "$PWD\r"

заканчивается:

can't read "word": no succh variable
while executing
"send PaS$word"



Последнее исправление: SymraKtz (всего исправлений: 3)

Ответ на: комментарий от Zubok

Не помогает, даже если я просто ввожу пароль в send (с \), возникает ошибка. Без \ половина пароля определяется как переменная.

SymraKtz
() автор топика
Ответ на: комментарий от SymraKtz

У меня, к сожалению, тут нет сразу ничего под рукой, чтобы я мог проверить.

Все то же самое: can't read «word»: no succh variable while executing «send PaS$word»

А двойной эскейп? «Pas\\\$word\r» напрямую в send

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от SymraKtz

И запусти expect с флагом "-d" (см. man expect), чтобы диагностику вывел. Что там покажет?

Zubok ★★★★★
()

Покажи весь код. А то у тебя он странно выглядит. Expect это Tcl, но в Tcl присваиваний типа PWD="something" не бывает.

TeopeTuK ★★★★
()
Ответ на: комментарий от DonkeyHot

Что-то не помогает, хотя ошибка изменилась на:
extra characters after close-quote
while executing

SymraKtz
() автор топика
Ответ на: комментарий от SymraKtz

Тогда это значит, что у тебя происходит двойное разыменование долларов. Сначала в баше, потом в тикле. Самый методически простой способ от этого избавиться, это выделить тиклевый код в отдельный скрипт, и запускать его из основного. Если хочется всё держать в одном файле, то однозначного рецепта я не знаю. Надо смотреть код целиком...

TeopeTuK ★★★★
()
Ответ на: комментарий от TeopeTuK

Собственно код, с некоторыми правками:


#!/bin/bash

set -x

USER="root"
PASSWD={"PaS\$word"}

LOG="ssh_conn.log"


EX="


set timeout 2

spawn ssh $USER@$localhost
expect "*(yes/no)?*" {send "yes\r"}
expect "*password:"
send "{$PASSWD}\r"

expect "root*"

expect "root*" {send 'echo "Test ok\r"'}
expect "root*" {send "exit\r"}
expect eof
"

expect -c "$EX" >> $LOG

SymraKtz
() автор топика

Пиши на tcl, а не Bash.

Тоесть

`#!/bin/expect` а не `#!/bin/sh`.

Далее, интерполируй строки в tcl стиле.

Deleted
()
Ответ на: комментарий от SymraKtz

Ну вот в таком виде проще на тикль переписать:

#!/usr/bin/expect

set USER "root"
set PASSWD {PaS$word}
set localhost localhost

puts $PASSWD

set LOG "ssh_conn.log"

set timeout 2

spawn ssh $USER@$localhost
expect "*(yes/no)?*" {send "yes\r"}
expect "*password:"
send $PASSWD\r

expect "root*"

expect "root*" {send 'echo "Test ok\r"'}
expect "root*" {send "exit\r"}
expect eof

TeopeTuK ★★★★
()
Последнее исправление: TeopeTuK (всего исправлений: 1)
Ответ на: комментарий от SymraKtz

Как я уже писал выше, результат тот же

Потому что у вас вот тут: EX=" двойные кавычки открываются, а вот тут: send "{$PASSWD}\r" закрываются и открываются заново.

vodz ★★★★★
()
Ответ на: комментарий от SymraKtz

А на шелле можно вот так ужасно с большим числом обратных косых:

#!/bin/bash

set -x

USER="root"
PASSWD="PaS\\\$word"
localhost=localhost

LOG="ssh_conn.log"


EX="

set timeout 2

spawn ssh $USER@$localhost
expect \"*(yes/no)?*\" {send \"yes\\r\"}
expect \"*password:\"
send \"$PASSWD\\r\"

expect \"root*\"

expect \"root*\" {send \"echo 'Test ok'\\r\"}
expect \"root*\" {send \"exit\\r\"}
expect eof
"

expect -c "$EX" >> $LOG

TeopeTuK ★★★★
()
Ответ на: комментарий от TeopeTuK

На bash-е это делается намного красивее:

#!/usr/bin/env bash
USER="root"
PASSWD='{PaS$word}'
localhost=localhost

read -r -d '' EX << EOF
set USER "$USER"
set PASSWD "$PASSWD"
set localhost $localhost
и так далее
EOF

expect -c "$EX" >> $LOG

vodz ★★★★★
()

Для таких случаев гуру придумали autoexpect

zolden ★★★★★
()
Ответ на: комментарий от vodz

Понимает, но подставляет внутри таких строк переменные. И фигурные скобки внутри кавычек не мешают постановке.

TeopeTuK ★★★★
()
Ответ на: комментарий от TeopeTuK

Понимает, но подставляет внутри таких строк переменные. И фигурные скобки внутри кавычек не мешают постановке.

Можно подумать, что если не использовать "", то переменные подставляться не будут... Надо просто решить, кто и где будет подставлять - bash или expect.

vodz ★★★★★
()

PWD=«PaS\$word»

это bash, гы-гы-гы?

в tcl переменные задаются так: set PWD {Pa$$w0rD}

$ expect
expect1.1> set PWD {Pa$$w0rD}
Pa$$w0rD
expect1.2> send "$PWD\r"
expect1.3> puts $PWD
Pa$$w0rD
futurama ★★★★★
()
Последнее исправление: futurama (всего исправлений: 1)
Ответ на: комментарий от vodz

Вот в твоем примере подставляет переменную $PASSWD как раз bash. Тикль видит буквально следующее: set PASSWD "{PaS$word}". Видишь, почему надо убрать кавычки?

TeopeTuK ★★★★
()
Ответ на: комментарий от TeopeTuK

Видишь, почему надо убрать кавычки?

Понял, вы конкретно только про PASSWORD, а про все. Да, там надо либо-либо. Я собственно не особо вчитывался, просто принцип показал.

vodz ★★★★★
()
Ответ на: комментарий от vodz

Да, принцип был хорош, без большого количества операций экранирования.

TeopeTuK ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.