我试图使用Plink(putty命令行)从VBA调用一组Unix命令,但命令没有被执行。我将发布代码,任何更正或建议都会有所帮助。
替代想法也是欢迎,我所要做的就是访问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
答案 0 :(得分:8)
一种选择是在plink
中打开WScript.Shell
会话,而不是使用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
发送命令之间添加一个短暂的等待。
答案 1 :(得分:5)
打开和写入文件的方式存在问题:
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 :(得分:1)
此方法创建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