【问题标题】:Call a Unix Script from Excel Vba从 Excel Vba 调用 Unix 脚本
【发布时间】:2014-01-14 18:28:15
【问题描述】:

我试图使用 Plink(putty 命令行)从 VBA 调用一组 Unix 命令,但这些命令没有得到 Executed。我会发布代码,任何更正或建议都会有所帮助。

也欢迎其他想法,我所要做的就是访问 unix 文件更改访问权限并将文件移动到其他文件夹。

请在下面找到代码

Public Sub Chgaccper()

Dim vPath As String
Dim vFile As String
Dim vSubpath As String
Dim vscript As String
Dim fNum As Long
Dim oShell

Set fso = CreateObject("scripting.filesystemobject")

vPath = ThisWorkbook.Path

'Mounting file command for ftp.exe
fNum = FreeFile()
Open vPath & "\Chg.txt" For Output As #1
Print #1, "c:\"
Print #1, "set PATH=" & vPath & ";%PATH% "
Print #1, " "
Print #1, "plink server Name -l uname -pw Password "
Print #1, " "
Print #1, "cd /root/home/temp "
Print #1, " "
Print #1, "chmod 666 *.csv "
Print #1, " "
Print #1, "cd /root/home/temp1 "
Print #1, " "
Print #1, "chmod 666 *.csv "
Print #1, " "
Print #1, "exit "
Print #1, " "
Close #1

vscript = "" & vPath & "\Chg.txt"

If fso.FolderExists("C:\Windows\System32") = False Then
Shell "C:\WINNT\system32\cmd.exe -s:" & vscript & ""
Else
Shell "C:\WINDOWS\system32\cmd.exe -s:" & vscript & ""

End If

SetAttr vPath & "\Chg.txt", vbNormal
Kill vPath & "\Chg.txt"


End Sub

【问题讨论】:

  • 你的代码的结果是什么?有没有Chg.txt,可以显示一下内容吗?当您尝试直接执行脚本时会发生什么?

标签: shell vba unix excel vbscript


【解决方案1】:

打开和写入文件的方式有问题:

fNum = FreeFile()
Open vPath & "\Chg.txt" For Output As #1
Print #1, "c:\"

您正在检查下一个可用的文件编号,将编号存储为变量“fNum”,然后以#1 打开文件,而不管 FreeFile() 返回什么。据我所知,您可能存在文件编号冲突。此外,在我的最后,“-s:”作为命令行参数失败。尝试改用 .cmd 文件,并将其作为命令调用:

Public Sub Chgaccper()

Dim vPath As String
Dim vFile As String
Dim vSubpath As String
Dim vscript As String
Dim fNum As Long
Dim oShell

Set fso = CreateObject("scripting.filesystemobject")

vPath = ThisWorkbook.Path

'Mounting file command for ftp.exe
fNum = FreeFile()
Open vPath & "\Chg.cmd" For Output As fNum
Print #fNum, "c:\"
Print #fNum, "set PATH=" & vPath & ";%PATH% "
Print #fNum, " "

Print #fNum, "plink server Name -l uname -pw Password "
Print #fNum, " "
Print #fNum, "cd /root/home/temp "
Print #fNum, " "
Print #fNum, "chmod 666 *.csv "
Print #fNum, " "
Print #fNum, "cd /root/home/temp1 "
Print #fNum, " "
Print #fNum, "chmod 666 *.csv "
Print #fNum, " "
Print #fNum, "exit "
Close #fNum

vscript = "" & vPath & "\Chg.cmd"

If fso.FolderExists("C:\Windows\System32") = False Then
    Shell "C:\WINNT\system32\cmd.exe /k " & vscript & ""
Else
    Shell "C:\WINDOWS\system32\cmd.exe /k " & vscript & ""
End If


SetAttr vPath & "\Chg.cmd", vbNormal
Kill vPath & "\Chg.cmd"

End Sub

参考:https://msdn.microsoft.com/en-us/library/office/gg264526.aspx

【讨论】:

    【解决方案2】:

    此方法创建 2 个文件。一个 (chg.bat) 调用 Plink 并登录到服务器。此外,它指示 Plink 执行第二个文件 (commands.txt) 中的命令。

    Public Sub Chgaccper()
    
        Dim vPath As String
        Dim vscript As String
    
        vPath = ThisWorkbook.Path
    
        Open vPath & "\Chg.bat" For Output As #1
        Print #1, "c:\"
        Print #1, "set PATH=" & vPath & ";%PATH% "
        Print #1, "plink ServerName -l uname -pw Password -m commands.txt"
        Close #1
        Open vPath & "\commands.txt" For Output As #2
        Print #2, "cd /root/home/temp"
        Print #2, "chmod 666 *.csv"
        Print #2, "cd /root/home/temp1"
        Print #2, "chmod 666 *.csv"
        Print #2, "exit"
        Close #2
    
        vscript = "" & vPath & "\Chg.bat"
    
        Shell vscript
    
        SetAttr vPath & "\Chg.bat", vbNormal
        SetAttr vPath & "\commands.txt", vbNormal
        Kill vPath & "\Chg.bat"
        Kill vPath & "\commands.txt"
    
    End Sub
    

    【讨论】:

      【解决方案3】:

      一种选择是在WScript.Shell 中打开plink 会话,而不是使用VBA 的Shell 通过脚本文件执行它。 plink 程序将从命令行以交互模式运行,WshExec 对象使您可以直接访问您正在执行的进程的标准输入和标准输出流。这个简短的示例演示了如何以交互方式使用它(它登录到公共 telehack.com telnet 服务器并执行fnord 命令),并将所有控制台输出复制到即时窗口中:

      Private Sub Fnord()
          Dim shell As Object
          Set shell = CreateObject("WScript.Shell")
          Dim console As Object
          'Open plink in interactive mode.
          Set console = shell.Exec("c:\putty\plink -telnet telehack.com -P 443")
          'Wait for a command prompt.
          WaitForResponseText console, "."
          'Send the fnord command to standard input.
          console.StdIn.Write ("fnord" & vbCr)
          'Wait for the server to echo it back.
          WaitForResponseText console, ".fnord"
          'Read the standard output through the next command prompt.
          WaitForResponseText console, "."
          'Exit the telent session.
          console.StdIn.Write ("exit" & vbCr)
      End Sub
      
      Private Sub WaitForResponseText(console As Object, response As String)
          Dim out As String
          'Make sure there's output to read.
          If console.StdOut.AtEndOfStream Then Exit Sub
          Do
              'Read a line from standard output.
              out = console.StdOut.ReadLine()
              'Not strictly required, but allows killing the process if this doesn't exit.
              DoEvents
              'Send the server output to the immediate window.
              Debug.Print out
              'Check for the response we're waiting for.
              If InStr(out, response) Then
                  Exit Do
              End If
          Loop Until console.StdOut.AtEndOfStream
      End Sub
      

      在您的情况下,与您连接的服务器没有太多“交互”,因此它可能就像直接将所有命令发送到 StdIn 一样简单。鉴于plink 具有广泛的协议支持,如果运行脚本文件与此有很大不同,我会感到惊讶:

      Public Sub Chgaccper()
          Dim shell As Object
          Set shell = CreateObject("WScript.Shell")
          Dim console As Object
          'Open plink in interactive mode.
          Set console = shell.Exec("c:\putty\plink server Name -l uname -pw Password")
          'Send your commands to the standard input.
          console.StdIn.Write ("cd /root/home/temp" & vbCr)
          console.StdIn.Write ("chmod 666 *.csv" & vbCr)
          console.StdIn.Write ("cd /root/home/temp1" & vbCr)
          console.StdIn.Write ("chmod 666 *.csv" & vbCr)
          console.StdIn.Write ("exit" & vbCr)
      End Sub
      

      如果运行速度过快,您可以随时进行测试以确保获得适当的服务器响应,或者在向StdIn 发送命令之间添加短暂的等待。

      【讨论】:

        猜你喜欢
        • 2012-10-19
        • 1970-01-01
        • 1970-01-01
        • 2016-06-22
        • 2021-04-23
        • 2011-06-01
        • 1970-01-01
        • 2023-03-13
        • 2013-08-10
        相关资源
        最近更新 更多