[Solved] Using TProcess to execute and interact with pacman package manager lazarus / 32-Linux ---------------------------------------------------------------------- SuperSathanas · 2024-05-20 15:38 I think that I have a couple different problems/things I lack understanding in that are causing me some issues here, so forgive me if I'm not being very clear or leaving out relevant information. I don't know what I don't know at this point. I'll be happy to provide more information if needed. Some background on what I'm doing: I have a bash script (appropriately named backupdate) that queries pacman for updateable packages, and if there are any, updates and ranks pacman's mirrors, creates a system snapshot using timeshift, performs pacman updates, then executes a separate program I wrote in FPC that gets rid of excessive timeshift snapshots, before optionally rebooting. This works fine, but I wanted to write the entire thing in FPC. I'm using TProcess to query pacman, run reflector to update and rank mirrors and call my other program, capture and act on their outputs, and that's all working fine. Where I'm running into an issue is with actually executing pacman and doing the updates. I need to call Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i pacman -Syu and then automatically have it respond to prompts and continue to capture the output to display to the user (me). I've managed to have it automatically respond to the prompt asking the user to proceed (:: Proceed with installation? [Y/n]), by scanning each line of the process's output, looking for a "y/n" or a variant thereof and writing a "y" to the input stream. However, after responding to the prompt and receiving the next line of output from pacman, ":: Retrieving packages...", nothing seems to happen. The TProcess instance keeps running, but I no longer receive any output from pacman, pacman seems to not move on (if I interrupt the process, no updates have been installed including no partial updates), and the whole program is just stuck waiting on that TProcess. However, if I don't write to the input stream, and just manually enter "y" when prompted, everything works and pacman does it's thing. Essentially what I'm trying to do is the equivalent of Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i yes | pacman -Syu in the terminal, just "yessing" through prompts. Currently, this is what the procedure that handles updates looks like. It's not optimal, but I'm not worried about cleaning it up and doing things more efficiently until I get my current problem solved. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure DoUpdates();varproc: TProcess;OList: TStringList;CheckString: String;I: Integer;  begin    OList := TStringList.Create();     proc := TProcess.Create(nil);    proc.Options := proc.Options + [poUsePipes, poWaitOnExit];    proc.CommandLine := 'pacman -Syu';    proc.Execute();     while proc.Running do begin      OList.LoadFromStream(proc.OutPut);       if OList.Count > 0 then begin        for I = 0 to OList.Count - 1 do begin          WriteLn(OList[I]);          CheckString := LowerCase(OList[I]);         if Pos('y/n', CheckString) <> 0 then begin            CheckString := 'y' + #10;            proc.Input.Write(CheckString[0], Length(CheckString));            proc.CloseInput();          end;       end;      end;     end;     proc.Free();    OList.Free();   end;  Not super sophisticated, but we're not too concerned with speed at this point. Any idea what it is about writing that "y" + #10 to the input stream is causing the whole thing to hang? It's weird to me that I'm able to respond to the prompt, get the next line of output from TProcess, but then it stalls, whereas if I do not handle the prompt programmatically, it all works. ---------------------------------------------------------------------- Roland57 · 2024-05-20 17:59 Hello! I suggest you to take a look at this demo: https://sourceforge.net/p/lazarus-ccr/svn/HEAD/tree/examples/process/ Unless I am wrong, it does what you are trying to do. ---------------------------------------------------------------------- SuperSathanas · 2024-05-20 20:00 That example does show a better way of waiting for and receiving output than what I did (waiting until TProcess.NumBytesAvailable > 0 instead of me just trying to read the output into a string list and then checking the length of list). My sloppiness there may be causing the issue, so I'll try doing it the way shown in the example and see if it still hangs. I see that they do not call TProcess.CloseInput(), whereas I currently am. I ended up adding that in to see if that would stop it from hanging, basically just throwing darts at the board when I was out of ideas, but I guess I'll go ahead and remove that as well and see how it goes with handling the output differently. ---------------------------------------------------------------------- SuperSathanas · 2024-05-21 00:41 Well, it turns out it was as simple as checking for TProcess.Output.NumBytesAvailable <> 0 instead of just trying to read the output into the string list each iteration. I guess maybe next time I won't be so sloppy, intending to fix things up later.