Tcl 期望脚本在远程服务器上找到文件存在

Tcl 期望脚本在远程服务器上找到文件存在,tcl,expect,Tcl,Expect,我正在编写一个expect脚本,以确定远程服务器上是否存在特定文件。我的测试服务器与远程服务器位于同一网络中。当我试图通过stackoverflow搜索类似的东西时,我所能找到的只是可以在本地服务器上工作的脚本 这个链接()是最近的 在类似的线路上,我发现以下网站: 期望脚本 基于这两个方面,我试图编写我的expect脚本- #! /usr/bin/expect set fileName [lindex $argv 0] set hostIp "10.0.0.1" puts "SSH to

我正在编写一个expect脚本,以确定远程服务器上是否存在特定文件。我的测试服务器与远程服务器位于同一网络中。当我试图通过stackoverflow搜索类似的东西时,我所能找到的只是可以在本地服务器上工作的脚本

这个链接()是最近的

在类似的线路上,我发现以下网站:

期望脚本 基于这两个方面,我试图编写我的expect脚本-

#! /usr/bin/expect

set fileName [lindex $argv 0]
set hostIp "10.0.0.1"

puts "SSH to server"
spawn sftp local@$hostIp
sleep 2
expect "Password:"
sleep 2
exp_send "local123\r"
sleep 2
expect "sftp> "
sleep 2
set prompt "sftp> "

exp_send "ls $fileName\r"
sleep 2

expect { 
"$fileName" { send_user "\n Found \n" }
"sftp>" { send_user "\n Not Found \n" }
}
不管对“ls$fileName”的响应如何,我都会得到“Found”的输出。预期部分的逻辑是——

发现逻辑 未找到逻辑 因此,在这两种情况下,脚本输出都是“找到”的,这是我无法获得逻辑的地方。如果文件存在,我希望文件名会弹出。否则,我希望看到消息“无法声明…”

问题
  • 可以期望检测到提示吗?我能把它存放在什么地方吗

  • 有没有更好的方法来查找远程服务器上是否存在文件

  • 我的剧本有问题吗


  • 提前感谢您的帮助

    Expect
    可以做tcl可以做的任何事情。当然,您可以将提示保存到某个变量中并进一步使用它

    set prompt "sftp> $"
    
    这个
    $
    符号在这里做什么?默认情况下,
    expect
    将与全局样式匹配,
    ^
    用于匹配字符串的开头,
    $
    用于匹配字符串的结尾

    您可以在代码中使用它作为

    expect $prompt
    
    无论您试图以何种方式获得,只有在涉及到
    expect
    时才是好方法

    我可以在你的脚本中看到一些问题。正如Brad Lanam指出的,您不应该使用文件名作为检查文件是否存在的匹配标准

    折衷的方法可以写成

    #!/usr/bin/expect
    if {$argc!=1} {
            puts "\nUsage : $argv0 <file-name>\n"
            exit
    }
    set prompt "sftp> $"; # To match 'sftp> ' at the end
    set filename [lindex $argv 0]; # User input
    set timeout 60; # 1 min 
    spawn sftp dinesh1,nmd@frs.sourceforge.net; # Replace this with your sftp server
    expect "Password:"
    send "mypassword\r"
    expect $prompt
    send "cd htdocs\r"
    expect $prompt
    send "ls $filename\r"
    expect {
            "No such file or directory" { puts "\n\n File  is not available :( \n\n" }
            -re "\n$filename\\s+\n$prompt" { puts "\n\n File is available :) \n\n" }
            timeout { puts "\n\n timeout happened :( \n\n" }
    }
    
    您可能想知道为什么在输出中会看到两次命令
    ls dinesh.txt
    。这是因为,生成的进程正在通过
    send
    回显正在发送的命令。(这是另一个故事。如果您感兴趣,请查看了解更多)

    为了匹配这一点,我使用正则表达式作为

    -re "\n$filename\\s+\n$prompt" 
    
    我想匹配的是:

    dinesh.txt
    sftp>
    
    \n
    -匹配上一行的新行

    $filename
    -这将替换为给定的文件名。i、 e.“dinesh.txt”

    \\s+
    -匹配多个空格

    $prompt
    -这将替换为“sftp>$”

    最后,我添加了
    timeout
    ,如果在
    expect发生超时的情况下。默认超时值是10秒,我在脚本中将其更改为60秒


    注意:如何知道文件名和提示之间有多个空格?为什么它不能像文件名、换行符和提示一样。通过观察输出,我们可以得出这样的结论。没有什么神奇的东西可以找到,而
    expect
    的选项是
    -d
    (或
    exp\u internal 1
    )也是有原因的。用这些选项触发它,您就是expect的专家。:)

    $fileName在“已找到”和“未找到”响应中都存在。@BradLanam-如果找到文件,“ls$fileName”的输出将是文件名本身。就像我们发现的逻辑一样。如果找不到文件,它将打印以下内容-无法统计远程文件:没有这样的文件或目录无法ls:“/file2.txt”not found sftp>感谢您对脚本的清晰解释。我现在已经了解了我的expect脚本是如何出现问题的。有了你的建议和投入,我已经成功地更新了我的脚本。它的工作方式与我预期的完全相同。谢谢你的帮助。
    sftp>ls dinesh.txt
    ls dinesh.txt
    dinesh.txt
    sftp> 
    
    -re "\n$filename\\s+\n$prompt" 
    
    dinesh.txt
    sftp>