Как включить двойные кавычки в команды Tcl или Expect для паролей или имен файлов с пробелами?

У меня есть два сценария для запуска в оболочке локального компьютера. Первый сценарий - это оболочка BASH, которая вызывает сценарий ожидания внутри себя. Оболочка bash выглядит следующим образом.

СЦЕНАРИЙ ОБОЛОЧКИ BASH SaveOnRemote.sh

#!/bin/bash
REMOTE_IP_ADDR="192.168.100.67"
REMOTE_PASS="some_pass_with_whitespaces"     
#The following line space is defined {\ }
PC_EXEC_FILE="/home/workspace/prog/Modified\ code/test/test_file"

#The following line space is included in the variable
TARGET_EXEC_FILE="/sd/1/test/test file target dir/target_file"

#Calling the expect script
scp_ToTarget.exp  $REMOTE_PASS $REMOTE_IP_ADDR $PC_EXEC_FILE $TARGET_EXEC_FILE

Конец сценария BASH SaveOnRemote.sh

И еще у нас есть скрипт scp_ToTarget.exp Tcl или Expect, который вызывается внутри оболочки bash.

Tcl Ожидайте СЦЕНАРИЙ scp_ToTarget.exp

#!/usr/bin/expect -f
set remote_password [lrange $argv 0 0]     
set remote_ipaddr [lrange $argv 1 1]   
set src [lrange $argv 2 2]    
set dst [lrange $argv 3 3]     
set timeout 3    
log_user 1

eval spawn scp $src root@$remote_ipaddr:$dst    
match_max 100000

#Look for passwod prompt
set timeout 5

expect {    
  "*?assword:*" {    
  send $remote_password\r\n    
  }    
}

## End of Tcl Expect SCRIPT scp_ToTarget.exp

Эти сценарии не работают, и я получаю сообщение об ошибке неизвестного каталога/файла.

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

Насколько я знаю, если я отправлю команду типа

scp "/tmp/try me.txt" [email protected]:"/sd/no tries/" 

это работает, и у меня нет проблем с пробелами. Но как только я нахожусь в Tcl и добавляю двойные кавычки в

"$src" или \"$src\" или "'$src'"

ни один из них не делает синтаксис именно таким, как я хочу, Tcl меняет двойные кавычки на фигурные скобки и т. д. Я застрял в этой проблеме, и я понятия не имею, как решить эту проблему ни в bash, ни в Ожидать или Tcl

Приветствуются любые хорошие ссылки или веб-ссылки для обработки различных строковых переменных в Bash/Tcl. Спасибо.


person Sina Sou    schedule 13.12.2012    source источник
comment
Для этой цели вам лучше использовать ключ ssh.   -  person gniourf_gniourf    schedule 13.12.2012
comment
удалите eval в eval spawn - это приведет к тому, что ваша команда не будет работать для параметров с пробелами.   -  person glenn jackman    schedule 14.12.2012


Ответы (3)


Вам необходимо использовать кавычки в сценарии оболочки при передаче параметров:

Это плохо:

scp_ToTarget.exp  $REMOTE_PASS $REMOTE_IP_ADDR $PC_EXEC_FILE $TARGET_EXEC_FILE

Это хорошо:

scp_ToTarget.exp "$REMOTE_PASS" "$REMOTE_IP_ADDR" "$PC_EXEC_FILE" "$TARGET_EXEC_FILE"

Поскольку вы не заключили переменные в кавычки, оболочка преобразует их в несколько слов, и сценарий Expect получает более параметров, чем 4.

Как только вы закавычите переменные в сценарии оболочки, Expect получит их, как вы и планировали.

person glenn jackman    schedule 13.12.2012
comment
Спасибо, я сделал следующее - person Sina Sou; 14.12.2012
comment
Какова цель eval REMOTE_PASS=$REMOTE_PASS? Результатом этого будет попытка установить REMOTE_PASS в первое слово пароля и попытаться выполнить остальные как команду: REMOTE_PASS="foo bar"; eval REMOTE_PASS=$REMOTE_PASS #==> bash: bar: command not found - person glenn jackman; 14.12.2012
comment
Да, вы правы, я должен удалить eval из REMOTE_PASS. - person Sina Sou; 19.12.2012
comment
Я так и не смог решить проблему с именами файлов, содержащими пробелы? Есть ли у вас какие-либо предложения? Спасибо - person Sina Sou; 19.12.2012
comment
вы использовали двойные кавычки в сценарии оболочки? Я показал вам, как это сделать. Это решение. - person glenn jackman; 19.12.2012

Спасибо, я реализовал следующим образом

REMOTE_PASS="some_pass_with_whitespaces"
REMOTE_PASS="\"$REMOTE_PASS\""
# I have no clue if the passwords with whitespace or \ works fine for password

#The following line space is defined {\ }
PC_EXEC_FILE="/home/workspace/prog/Modified\ code/test/test_file"
eval PC_EXEC_FILE=$PC_EXEC_FILE
PC_EXEC_FILE="\"$PC_EXEC_FILE\""

#The following line space is included in the variable
TARGET_EXEC_FILE="/sd/1/test/test file target dir/target_file"
eval TARGET_EXEC_FILE=$TARGET_EXEC_FILE
TARGET_EXEC_FILE="\"$TARGET_EXEC_FILE\""

# The script is supposed to handle strings with {spc} and {\spc} used for
# directories but the filenames can not contain spaces 

#Calling the expect script
eval scp_ToTarget.exp  $REMOTE_PASS $REMOTE_IP_ADDR $PC_EXEC_FILE $TARGET_EXEC_FILE

В файле ожидания я добавил строку после ожидания {

  "*?assword:*" {    
  send $remote_password\r\n  
  interact 
  }    

Это решает проблему с пробелами в каталогах, но не в именах файлов!

Я все еще не понимаю, как решить пробелы в имени файла :(

person Sina Sou    schedule 14.12.2012

Устранит ли проблему использование такой строки:

REMOTE_PASS="\\\"$REMOTE_PASS\\\""

Это "двойной побег", о чем, как я полагаю, вы просили.

(Я знаю, что это старый вопрос, но я нашел его при поиске в Google, как и другие... и они могут быть признательны, если найдут хотя бы то, что, наконец, решило мою проблему.)

person Lars    schedule 04.10.2017