问题陈述:我只是想启动HUB和Node来使用Selenium Grid执行一些测试。 我有两个批处理文件START HUB.bat和START NODE.bat,当我手动运行它们时运行完美。 但我希望它们使用Java程序@BeforeMethod运行。 我寻找答案
Runtime.getRuntime().exec("cmd /C start \"./BatchFiles/START HUB.bat\"");
这会打开CMD,但会转到我的.git项目的路径,但不会运行bat文件。
我尝试使用Process Builder但是没有打开cmd。
ProcessBuilder pb = new ProcessBuilder("cmd", "/C"," start", "START HUB.bat");
File dir = new File("D:\\work\\GIT REPOSITORY\\project.selenium.maven.jenkinsCI\\BatchFiles");
pb.directory(dir);
Process p = pb.start();
有人可以帮我解决这个问题。以下是批处理文件中的命令。
D:
cd work
java -jar selenium-server-standalone-3.4.0.jar -role hub
答案 0 :(得分:1)
所以你想要执行命令行:
cmd /C start "./BatchFiles/START HUB.bat"
在命令行开头使用cmd
时,已经开始执行%SystemRoot%\System32\cmd.exe
的新命令进程。使用选项/C
显式请求运行命令后,此命令进程应自动关闭,这意味着关闭,因为它可以在命令提示符窗口cmd /?
中运行时读取。
在此命令过程中执行的命令是:
start "./BatchFiles/START HUB.bat"
start
的内部命令cmd.exe
用于在新进程中启动可执行文件或脚本。在命令提示符窗口start /?
中运行时,可以阅读其帮助。
第一个双引号字符串由start
解释为在新命令进程中应执行批处理文件或控制台应用程序时打开的新命令进程窗口的标题。
这就是为什么不执行批处理文件的原因,因为"./BatchFiles/START HUB.bat"
被解释为窗口标题字符串。
在Windows上,目录分隔符为\
,而不是Unix上的/
。正如您在/
上看到的那样,/C
用作选项的开头。但Windows处理/
文件路径通常也是正确的,因为在目录/文件名中用/
替换每个\
时,在访问目录或文件时使用绝对路径或相对路径。
所以解决方案是使用
Runtime.getRuntime().exec("cmd.exe /C start \"start hub\" \".\\BatchFiles\\START HUB.bat\"");
或使用
Runtime.getRuntime().exec("cmd.exe /C \"BatchFiles\\START HUB.bat\"");
以目录或文件名开头的路径相对于Windows上正在运行的进程的当前目录,例如在目录或文件名字符串的开头使用.\
。
第一个代码启动一个命令进程,该进程执行命令start
,该命令启动另一个命令进程,标题start hub
执行批处理文件。以cmd.exe
开始的第一个命令进程在运行start
后立即终止,而批处理文件在第二个启动的命令进程中执行。这意味着在并行执行批处理文件时,Java应用程序将继续运行。
第二个代码导致在使用cmd.exe
启动的单个命令进程中执行批处理文件,并停止执行Java应用程序,直到完成整个批处理文件。
可以使用以下方法删除批处理文件的使用:
Runtime.getRuntime().exec("cmd.exe /C start \"start hub\" /D D:\\work java.exe -jar selenium-server-standalone-3.4.0.jar -role hub");
使用/D D:\work
,为执行java.exe
及其参数的命令进程定义了工作目录。
或者不使用start
命令:
Runtime.getRuntime().exec("cmd.exe /C cd /D D:\\work && java.exe -jar selenium-server-standalone-3.4.0.jar -role hub");
在命令提示符窗口cd /?
中运行以获取有关cd /D D:\work
的帮助,并参阅Single line with multiple commands using Windows batch file以获取此处使用的运算符&&
的说明,以指定在一行上执行的两个命令只有当java.exe
成功将工作目录更改为cd
时,才会执行D:\work
。
答案 1 :(得分:0)
func describeNode(node *api.Node, nodeNonTerminatedPodsList *api.PodList, events *api.EventList, canViewPods bool) (string, error) {
return tabbedString(func(out io.Writer) error {
fmt.Fprintf(out, "Name:\t%s\n", node.Name)
fmt.Fprintf(out, "Role:\t%s\n", findNodeRole(node))
printLabelsMultiline(out, "Labels", node.Labels)
printTaintsInAnnotationMultiline(out, "Taints", node.Annotations)
fmt.Fprintf(out, "CreationTimestamp:\t%s\n", node.CreationTimestamp.Time.Format(time.RFC1123Z))
fmt.Fprintf(out, "Phase:\t%v\n", node.Status.Phase)
if len(node.Status.Conditions) > 0 {
fmt.Fprint(out, "Conditions:\n Type\tStatus\tLastHeartbeatTime\tLastTransitionTime\tReason\tMessage\n")
fmt.Fprint(out, " ----\t------\t-----------------\t------------------\t------\t-------\n")
for _, c := range node.Status.Conditions {
fmt.Fprintf(out, " %v \t%v \t%s \t%s \t%v \t%v\n",
c.Type,
c.Status,
c.LastHeartbeatTime.Time.Format(time.RFC1123Z),
c.LastTransitionTime.Time.Format(time.RFC1123Z),
c.Reason,
c.Message)
}
}
addresses := make([]string, 0, len(node.Status.Addresses))
for _, address := range node.Status.Addresses {
addresses = append(addresses, address.Address)
}
printResourceList := func(resourceList api.ResourceList) {
resources := make([]api.ResourceName, 0, len(resourceList))
for resource := range resourceList {
resources = append(resources, resource)
}
sort.Sort(SortableResourceNames(resources))
for _, resource := range resources {
value := resourceList[resource]
fmt.Fprintf(out, " %s:\t%s\n", resource, value.String())
}
}
fmt.Fprintf(out, "Addresses:\t%s\n", strings.Join(addresses, ","))
if len(node.Status.Capacity) > 0 {
fmt.Fprintf(out, "Capacity:\n")
printResourceList(node.Status.Capacity)
}
if len(node.Status.Allocatable) > 0 {
fmt.Fprintf(out, "Allocatable:\n")
printResourceList(node.Status.Allocatable)
}
fmt.Fprintf(out, "System Info:\n")
fmt.Fprintf(out, " Machine ID:\t%s\n", node.Status.NodeInfo.MachineID)
fmt.Fprintf(out, " System UUID:\t%s\n", node.Status.NodeInfo.SystemUUID)
fmt.Fprintf(out, " Location:\t%s\n", node.Status.NodeInfo.Location)
fmt.Fprintf(out, " Boot ID:\t%s\n", node.Status.NodeInfo.BootID)
fmt.Fprintf(out, " Kernel Version:\t%s\n", node.Status.NodeInfo.KernelVersion)
fmt.Fprintf(out, " OS Image:\t%s\n", node.Status.NodeInfo.OSImage)
fmt.Fprintf(out, " Operating System:\t%s\n", node.Status.NodeInfo.OperatingSystem)
fmt.Fprintf(out, " Architecture:\t%s\n", node.Status.NodeInfo.Architecture)
fmt.Fprintf(out, " Container Runtime Version:\t%s\n", node.Status.NodeInfo.ContainerRuntimeVersion)
fmt.Fprintf(out, " Kubelet Version:\t%s\n", node.Status.NodeInfo.KubeletVersion)
fmt.Fprintf(out, " Kube-Proxy Version:\t%s\n", node.Status.NodeInfo.KubeProxyVersion)
if len(node.Spec.PodCIDR) > 0 {
fmt.Fprintf(out, "PodCIDR:\t%s\n", node.Spec.PodCIDR)
}
if len(node.Spec.ExternalID) > 0 {
fmt.Fprintf(out, "ExternalID:\t%s\n", node.Spec.ExternalID)
}
if canViewPods && nodeNonTerminatedPodsList != nil {
if err := describeNodeResource(nodeNonTerminatedPodsList, node, out); err != nil {
return err
}
} else {
fmt.Fprintf(out, "Pods:\tnot authorized\n")
}
if events != nil {
DescribeEvents(events, out)
}
return nil
})
}
您是否尝试将绝对路径传递给class RunFile
{
public static void main(String[] arg){
Runtime runtime = null;
try{
runtime.getRuntime.exec("cmd /C start \"D:\\work\\GIT REPOSITORY\\project.selenium.maven.jenkinsCI\\BatchFilesmyBatchFile.bat\\START HUB.bat\"");
}
catch(RuntimeException e){
e.printStackTrace();
}
}
}
函数?
除了引用路径之外,因为您在exec
和START
答案 2 :(得分:0)
@Mofi的解释真的有助于理解cmd如何对待每一个“/”。
Runtime.getRuntime().exec("cmd.exe /C start \"start hub\" \".\\BatchFiles\\START HUB.bat\"");
以上是适用于我的解决方案。