首页 > 解决方案 > 在 Ubuntu 中连接到 VPN

问题描述

我使用了 VPN 服务并使用 java 代码连接到它并在 Ubuntu 上运行它。每当 sudo openvpn 命令完全运行时,控制台就会卡住并且在 while 循环之后不会转到代码。但是如果我包含代码在while循环内的sudo命令之后,它运行之后的代码,而不是sudo命令。我尝试添加“&”以便命令在后台运行但没有用。请提出一种方法来执行此操作,因为我尝试了各种解决方案但都是徒劳的。下面是我编写的代码。

public class curl {


void sudo() throws IOException {

    String command1 = "sudo openvpn --config /etc/openvpn/configFile ";

     System.out.println(command1);



     Process curlProc1;

    curlProc1 = Runtime.getRuntime().exec(command1);



    DataInputStream curlIn1 = new DataInputStream(

            curlProc1.getInputStream());

      String outputString1;

     while ((outputString1 = curlIn1.readLine()) != null) {

        System.out.println(outputString1);

}


     String urly = "MyURL";
             URL obj = new URL(urly);
             HttpURLConnection con1 = (HttpURLConnection) obj.openConnection();

             con1.setRequestMethod("GET");

           con1.setDoOutput(true);

             int responseCode = con1.getResponseCode();
             System.out.println("Response Code : " + responseCode);

             BufferedReader iny = new BufferedReader(
             new InputStreamReader(con1.getInputStream()));
               String output;
               StringBuffer response = new StringBuffer();

               while ((output = iny.readLine()) != null) {
                response.append(output);

               }

               iny.close();
               System.out.println(response.toString());
               }

public static void main(String args[]) throws IOException, ClassNotFoundException, SQLException, JSONException{

     curl brc= new curl();
     brc.sudo();

}



}

标签: javaubuntu

解决方案


您的问题是由 sudo 输出到错误流的事实引起的。这正在发生:

curlProc1 = Runtime.getRuntime().exec(command1);
  1. 你的程序启动 sudo
  2. 由于 sudo 默认在终端上工作,它输出“sudo: no tty present and no askpass program specified”或“Password:”到stderr
while ((outputString1 = curlIn1.readLine()) != null) {
  1. 你的程序等待输入stdout
  2. 由于您从未阅读过标准错误,sudo 将永远不会终止,因此,sudo 永远不会关闭标准输出,因此您的程序会卡住

解决此问题的一种快速方法是使用process builder,它具有将 thestderr和 the组合stdout在单个流中的有用选项,这意味着您只需要 1 个线程来读取流,并保持代码简单。

ProcessBuilder pb =
    new ProcessBuilder("sudo", "openvpn", "--config", "/etc/openvpn/configFile");
pb.redirectErrorStream(true);
Process curlProc1 = pb.start();
....

由于 sudo 可能会要求输入密码(您可以将其配置为要求输入密码而不是给出错误),因此您可以在 收到密码提示通过写入进程的输入流来提供密码:

p.getOutputStream().write("correct battery horse staple\n".getBytes(STandardCharsets.UTF_8));

推荐阅读