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
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
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.
procedure DoUpdates();
var
proc: 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.