مشكلة في الاتصال بـ rsync+ssh من Java على نظام التشغيل Windows

StackOverflow https://stackoverflow.com/questions/686701

  •  22-08-2019
  •  | 
  •  

سؤال

أواجه مشكلة في الاتصال بـ rsync من Java على نظام التشغيل Windows Vista مع تثبيت cygwin.من الغريب أن لصق نفس الأمر بالضبط في غلاف الأوامر يعمل بشكل جيد.

تبدو مكالمة جافا الاختبارية الخاصة بي هكذا.

String[] envVars = {"PATH=c:/cygwin/bin;%PATH%"};
File workingDir = new File("c:/cygwin/bin/");
Process p = Runtime.getRuntime().exec("c:/cygwin/bin/rsync.exe -verbose -r -t -v --progress -e ssh /cygdrive/c/Users/dokeeffe/workspace/jrsync/ www.servername.net:/home/dokeeffe/rsync/",envVars,workingDir);

ثم أبدأ خيطين لقارئ الدفق لالتقاط وتسجيل inputStream وerrorStream للعملية ص.

هنا الناتج ....

DEBUG: com.mddc.client.rsync.StreamGobbler - opening connection using: ssh www.servername.net rsync --server -vvtre.iLs . /home/dokeeffe/rsync/
DEBUG: com.mddc.client.rsync.StreamGobbler - rsync: pipe: Operation not permitted (1)
DEBUG: com.mddc.client.rsync.StreamGobbler - rsync error: error in IPC code (code 14) at /home/lapo/packaging/rsync-3.0.4-1/src/rsync-3.0.4/pipe.c(57) [sender=3.0.4]

رمز rsync الذي يحدث فيه الخطأ هو Pipe.c(57) وهو هذا.

if (fd_pair(to_child_pipe) < 0 || fd_pair(from_child_pipe) < 0) {
    rsyserr(FERROR, errno, "pipe");
    exit_cleanup(RERR_IPC);
}

لذلك، لسبب ما، يكون fd_pair(to_child_pipe) < 0 أو fd_pair(from_child_pipe) < 0.

إذا كان لدى أي شخص أي اقتراحات سيكون أمرا رائعا لأنني عالقة الآن.شكرًا،

هل كانت مفيدة؟

المحلول

هل توزيع سيغوين لثنائي رسينك تعترف الأمر سه؟ الأمر الذي تحاول تنفيذه ربما يعمل بشكل جيد عندما كنت وضعت في وعاء لشيء من هذا القبيل باش يعرف كيفية تفسير الأمر سه لتأسيس اتصال، أي استخدام البرنامج سه لإنشاء اتصال لبرنامج رسينك. من تصحيح المعلومات الخاصة بك أعتقد رسينك تتوقع اتصال ولكن بدلا من ذلك يتلقى السلسلة "سه ..." التي فشلت في الأنابيب.

لالتفاف حول هذا لديك للسماح باش للقيام بهذا العمل بالنسبة لك. انظروا هذه الصفحة في القسم الخاص المواضيع تميل الطفل. قد تحتاج إلى مفترق مثيل قذيفة القيادة وإرسال الأوامر الخاص بك إلى قذيفة فرعي أو جانبي. ذلك شيء من هذا القبيل:

Process p = Runtime.getRuntime().exec("c:/cygwin/bin/bash.exe");
OutputStreamWriter osw = new OutputStreamWriter(p.getOutputStream());
BufferedWriter bw = new BufferedWriter( osw, 100);
try{
    bw.write(command);
    bw.close();
}catch(IOExeception e){
    System.out.println("Problem writing command.");
}

وربما كنت ترغب في قراءة الناتج العمليات جدا لأنها سوف توقف تنفيذ إذا كنت لا تقرأ عليه. الارتباط المنصوص يغطي هذا الموضوع جيدا.

نصائح أخرى

هل لديك سه الخاص / العام تخزين المفاتيح في مكان ما كنت قد نسيت؟

ولقد حاولت أبدا القراءة / الكتابة باستخدام موضوع مختلف، إلا أن نفس الخيط الذي تنفيذ الأمر. يمكن أن يكون هذا يسبب مشكلة لديك؟

ويمكنك أيضا محاولة تمرير -v إلى SSH للحصول على إخراج التصحيح. وقد ساعد ذلك لي في الماضي لحل مشاكل اتصال SSH. هل تمر -e "ssh -v".

وشكرا للجميع إسبانيا دانيال. الرابط الذي أرسلني هو عظيم. في النهاية كنت ProcessBuilder بدلا من Runtime.exec. هنا هو رمز إذا كان لها أي مساعدة لأي شخص .....

            ProcessBuilder pb = new ProcessBuilder(new String[]{"c:/cygwin/bin/rsync.exe"
                                                                ,"-verbose",
                                                                "-r",
                                                                "-t",
                                                                "-v",
                                                                "--progress",
                                                                "-e",
                                                                "ssh",
                                                                "/cygdrive/c/Users/dokeeffe/workspace/jrsync/",
                                                                "www.servername.net:/home/dokeeffe/rsync/"});
        Map<String, String> env = pb.environment();
        env.put("PATH","/cygwin/bin;%PATH%");
        pb.directory(new File("c:/cygwin/bin/"));
        Process p = pb.start();
        StreamGobbler outputGobbler = new StreamGobbler(p.getInputStream(),"OUTPUT");
        StreamGobbler errorGobbler = new StreamGobbler(p.getErrorStream(),"ERROR");
        outputGobbler.start();
        errorGobbler.start();
        int val = p.waitFor();
        if(val!=0){
            throw new Exception("Rsync return code="+val);
        }

تجربتي مع مشكلة مماثلة:

ثوابتي:

  1. كان نظام البناء ANT، ويعمل في هدسون

  2. خادم البناء هو Windows Server

  3. خادم الاختبار عن بعد هو Linux

  4. غير مسموح باستخدام برنامج rsync الخفي فقط rsync عبر ssh

ماذا فعلنا

  1. تم تثبيت DeltaCopy على خادم ويندوز

  2. اتبع هذه التعليمات لإعداد DeltaCopy بحيث يعمل مع SSH

  3. لقد قمت ببناء ماكرو ANT التالي، وقمت بتشغيله في هدسون.في البداية علق هذا في ذهني، دون أي رد.

    إضافة -vvv بدلا من -v صنعت مختلفة.أدى هذا إلى إضافة المزيد من المعلومات إلى سجل هدسون.

    <macrodef name="rsync">
    <attribute name="username"/>
    <attribute name="remoteServer"/>
    <attribute name="remoteDir"/>
    <attribute name="sourceDir"/> <!-- relative to basedir start and end with / (e.g. "/html/resources/" -->
    <sequential>
        <echo message="Starting rsync @{sourceDir} to @{remoteDir} on server @{remoteServer} as user @{username} at ${release.start}"/>
    
        <pathconvert property="cygwinbasepath" dirsep="/" pathsep="" description="Replace ':' '\' with '/' and assign value to property">
            <path path="${basedir}" description="Original version" />
            <!--Pathconvert will try to add the root directory to the "path", replace with empty string --> 
            <filtermapper> 
                <replacestring from=":" to="" />  
            </filtermapper>
        </pathconvert>
        <echo message="${basedir} converted to ${cygwinbasepath}"/>
    
        <property name="rsync.cygwinSourcePath" value="/cygdrive/${cygwinbasepath}@{sourceDir}" />
        <!-- ${rsync.user}@${rsync.server}:${rsync.dir} -->
        <property name="rsync.remoteDestinationPath" value="@{remoteServer}:@{remoteDir}" />
    
        <echo message="trying to run:" />
        <!-- &quot; is escaped quote -->
        <echo>cmd /C rsync -avz -e &quot;ssh -v -l ${deployment.rsync.username} -i /cygdrive/C/cygwin/home/service-tomcat/.ssh/id_rsa&quot; --recursive --chmod=a=rw,Da+x ${rsync.cygwinSourcePath} ${rsync.remoteDestinationPath}</echo>
        <echo>
        </echo>
        <!-- 10 minute timeout -->
        <exec executable="C:\cygwin\bin\mintty.exe"
            timeout="300000"
        >
            <arg value="rsync"/>
              <arg value="-avvvz"/>
              <arg value="-e" />
              <arg value="ssh -v -l ${deployment.rsync.username} -i /cygdrive/C/cygwin/home/vj-service-tomcat/.ssh/id_rsa" />
              <arg value="--recursive"/>
              <arg value="--chmod=a=rw,Da+x"/> 
              <arg value="${rsync.cygwinSourcePath}"/>
              <arg value="${rsync.remoteDestinationPath}"/>
        </exec>
    
        <echo>
        </echo>
    
    </sequential>
    

    كان المفتاح لتفعيل هذا هو التنفيذ C:\cygwin\bin\mintty.exe بدلا من cmd.

  4. قمت بعد ذلك بتشغيل الأمر rsync يدويًا على خادم Windows، ويتم تحديث ملفknown_hosts الخاص به باستخدام المضيف البعيد.كان لا بد من القيام بذلك كمستخدم هدسون.استخدمنا الأمر runas في نظام التشغيل Windows لتشغيل وحدة تحكم cygwin كمستخدم Hudson.

وأنا في الآونة الأخيرة نفذت شيئا من هذا القبيل، ويعتقد أن حصة تجربتي، واستغرق الأمر بعض الوقت لتصحيح هذه المشكلة. هذا السؤال هو واحد من الحالات الوحيدة لهذه المشكلة على جوجل.

وكان يجري إطلاقها طلبي كخدمة. عند تشغيل الأمر whoami، وكانت النتيجة "الإقليم الشمالي سلطة \ النظام". بعد الإعداد مفاتيح SSH بلدي تحت /home/myusername/.ssh، الأمر رسينك كانت فاشلة حيث لم يتم تحديد التكوين تحت /home/SYSTEM/.ssh.

ونسخ الدليل /home/myusername/.ssh جهدي ل/home/SYSTEM/.ssh واستخدام عملت مجموعة سلسلة التالية لأغراض بلدي. استبدال PORT مع منفذ سه الخاص بك.

new String[]{"rsync", "-z", "-I", "-e", "ssh -p PORT", server + ":" + serverPath, clientPath}

وأنظر الرابط هنا للحصول على تفاصيل حول إطلاق CMD.EXE تحت امتيازات النظام لأغراض الاختبار إذا كانت هذه هي مشكلتك.

scroll top