带有 space 的字符串作为一个单一的 Expect 脚本参数

String with space as one single Expect script argument

我正在使用 expect 来模拟 sftp 交互式提示 (download_from_sftp.exp):

#!/usr/bin/expect

set username [lindex $argv 0];
set server [lindex $argv 1]
set password [lindex $argv 2];
set source [lindex $argv 3];
set target [lindex $argv 4];
set timeout 2400;

spawn sftp "$username@$server"
expect "password:"
send "$password\n"
expect "sftp>"
send "get ${source} ${target}\n"
expect "sftp>"
send "bye\n"
interact

其中$targe是包含space的输出目录:(

我怎样才能传递参数以便它被视为一个参数?目前我正在使用类似的东西:

cmd="${git_directory}/sh/download_from_sftp.exp $sftp_username 
$sftp_server $sftp_password ${src_xml} ${target_xml}"
$cmd # run

其中最后一个参数将被展开。

您可以用引号将参数括起来:

cmd="${git_directory}/sh/download_from_sftp.exp $sftp_username $sftp_server$sftp_password \"${src_xml}\" \"${target_xml}\""
$cmd # run

在 shell 中,您不能 "serialize" 将带有参数的命令转换为单个字符串,并使命令反序列化,其中一些空格作为常规空格,一些作为 "special" 空格。

你需要使用一个shell数组(bash,ksh,zsh都有数组)

cmd=( 
    "$git_directory/sh/download_from_sftp.exp"
    "$sftp_username"
    "$sftp_server"
    "$sftp_password"
    "$src_xml"
    "$target_xml"
)
"${cmd[@]}" # run

所有这些引号都是必需的。

这是将包含空格的参数可靠地保持为单个实体的唯一方法。

在期望中,您可能必须引用参数(为了 sftp)

send "get $source \"$target"\r"

通常情况下,您发送 \r 而不是 \n -- \r 是一个回车 return,或者 "hitting enter"