Hallo, zusammen!<div><br></div><div>Ich stecke gerade fest und weiß nicht mehr weiter, so dachte ich mir schreie ich doch gleich hier mal um Hilfe.</div><div><br></div><div>Die Umgebung:</div><div>Ich habe in der Arbeit mehrere Testrechner die automatisierte Tests fahren. Ab und zu ist es aber notwendig auf allen Maschinen Arbeiten durchzuführen, was dann meist wieder durch Scripts erledigt wird (SVN checkout, kopieren von files...).</div>
<div><br></div><div>Die Idee:</div><div>Um nicht immer von Rechner zu Rechner laufen zu müssen um File XY zu kopieren, dachte ich mir da muß eine Perllösung her. Die Idee war das Perl auf einem Port lauscht und von dort dann auf Jobs wartet, wie starte script XY.</div>
<div><br></div><div>Das Problem:</div><div>So weit so gut. Der Server lief recht schnell, aber wie die Scripte starten. Dazu benutze folgenden Code:</div><div><br></div><div><div>sub start_script {</div><div><span class="Apple-tab-span" style="white-space:pre">     </span>my ($script, $interpreter) = @_;</div>
<div><span class="Apple-tab-span" style="white-space:pre">      </span></div><div><span class="Apple-tab-span" style="white-space:pre">     </span>my $cmd;</div><div><span class="Apple-tab-span" style="white-space:pre">     </span>if($interpreter && $script) {</div>
<div><span class="Apple-tab-span" style="white-space:pre">              </span>$log->info("Start '$interpreter' with '$script'");</div><div><span class="Apple-tab-span" style="white-space:pre">              </span></div>
<div><span class="Apple-tab-span" style="white-space:pre">              </span>$cmd = $interpreter." ".$script;</div><div><span class="Apple-tab-span" style="white-space:pre">   </span>}</div><div><span class="Apple-tab-span" style="white-space:pre">    </span>elsif ($script){</div>
<div><span class="Apple-tab-span" style="white-space:pre">              </span>$log->info("Start '$script'");</div><div><span class="Apple-tab-span" style="white-space:pre">          </span>$cmd = $script;</div><div><span class="Apple-tab-span" style="white-space:pre">      </span>}</div>
<div>        else {</div><div>                 $log->logcroak("nothing to start!");</div><div>                 return;</div><div>        }</div><div><span class="Apple-tab-span" style="white-space:pre"> </span></div>
<div><span class="Apple-tab-span" style="white-space:pre">      </span># create temp file for the error output</div><div><span class="Apple-tab-span" style="white-space:pre">      </span>my $tempfh = File::Temp->new(UNLINK => 0, SUFFIX => '.dat');</div>
<div><span class="Apple-tab-span" style="white-space:pre">      </span>my $tempFilename = $tempfh->filename();</div><div><span class="Apple-tab-span" style="white-space:pre">   </span></div><div><span class="Apple-tab-span" style="white-space:pre">     </span># assemble command with stderr and stdin redirection.</div>
<div><span class="Apple-tab-span" style="white-space:pre">      </span>$cmd = "$cmd 2>$tempFilename";</div><div><span class="Apple-tab-span" style="white-space:pre">  </span>$log->debug("start: '".$cmd."'");</div>
<div><span class="Apple-tab-span" style="white-space:pre">      </span></div><div><span class="Apple-tab-span" style="white-space:pre">     </span># start script. ATM without timeout</div><div><span class="Apple-tab-span" style="white-space:pre">  </span>open(my $scriptFH, "-|", $cmd) or $log->logcroak("Could not start script: $cmd");</div>
<div><span class="Apple-tab-span" style="white-space:pre">      </span>binmode $scriptFH, ":utf8";</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>my $stdout = join "", <$scriptFH>; # join initialized the variable with "" if nothing comes from readline (<>)</div>
<div><span class="Apple-tab-span" style="white-space:pre">      </span>close($scriptFH);</div><div><span class="Apple-tab-span" style="white-space:pre">    </span></div><div><span class="Apple-tab-span" style="white-space:pre">     </span>my $exitCode = $?;</div>
<div><span class="Apple-tab-span" style="white-space:pre">      </span></div><div><span class="Apple-tab-span" style="white-space:pre">     </span>my $stderr = slurp($tempFilename);</div><div><span class="Apple-tab-span" style="white-space:pre">   </span></div>
<div><span class="Apple-tab-span" style="white-space:pre">      </span>return ($stdout, $stderr, $exitCode);</div><div>}</div></div><div><br></div><div>Das funktioniert für sich genommen so wie erwartet. In meinem Serverscript allerdings kommt immer die Fehlermeldung:</div>
<div>The process cannot access the file because it is being used by another process</div><div><br></div><div>Der ExitCode is dann 256 und $stdout und $stderr ist immer leer.</div><div>Die Fehlermeldung wird auf der commandline immer auf STDERR ausgegeben. Nach einigem Herumprobieren scheint es diese Zeile zu sein die den Fehler produziert:</div>
<div>my $stdout = join "", <$scriptFH>;</div><div><br></div><div>Hat jemand eine Ahnung was da passiert? Wie gesagt, kopiert in ein extra File tut der Code was er soll.</div><div>Das Serverscript tut aber nichts anderes als diese Funktion aufzurufen, ich kann mir nicht erklären was das Problem verursacht.</div>
<div>Der Serverthread ist auch single-threaded. Also kein Fork oder ähnliches der einen neuen Process erzeugen würde (war für die Zukunft geplant).</div><div><br></div><div>Danke,</div><div>Wolfgang</div>