Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Otros entornos y lenguajes > Lazarus, FreePascal, Kylix, etc.
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 11-01-2006
pkbza pkbza is offline
Miembro
 
Registrado: may 2004
Posts: 48
Poder: 0
pkbza Va por buen camino
Capturar salida de comando linux

Hola foro del clubdelphi
Tengo una pequeña aplicacion en kylix que necesita ejecutar comandos en linux, bueno eso lo hago sin mayor problema con execl, el problema es que ahora tambien necesito rescatar o capturar la salida de un comando (que es solo una linea, siempre) y guardarlo en alguna variable de mi programa, no he encontrado forma de hacerlo, aca tampoco he encontrado algun hilo sobre el tema, si alguien ha hecho eso alguna vez le pediria que me alludase porfavor, gracias de antemano.
Responder Con Cita
  #2  
Antiguo 12-01-2006
Avatar de mg1821
mg1821 mg1821 is offline
Miembro
 
Registrado: may 2003
Ubicación: lima
Posts: 69
Poder: 21
mg1821 Va por buen camino
tienes que colocar en el uses el libC
creo que navegando en el foro puedes encontrar al respecto. borland publico al respecto hace tiempo, tengo el archivo pero increiblemente no lo puedo adjuntar ya que me bota error de archivo. (uhm.....sera que no puedo adjuntar desde linux?.......no creo.....)
__________________
mg1821
Responder Con Cita
  #3  
Antiguo 12-01-2006
Avatar de jachguate
jachguate jachguate is offline
Miembro
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 6.254
Poder: 27
jachguate Va por buen camino
Tomá en cuenta que adjuntar archivos tiene un límite (bastante restrictivo) de tamaño.

No será que es un archivo mas grande de lo aceptado?
__________________
Juan Antonio Castillo Hernández (jachguate)
Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate
Responder Con Cita
  #4  
Antiguo 12-01-2006
pkbza pkbza is offline
Miembro
 
Registrado: may 2004
Posts: 48
Poder: 0
pkbza Va por buen camino
comando linux

Gracias mg1821, pero en el foro no he encontrado nada sobre eso... efectivamente utilizo libC para ejecutar los comandos, pero no se como rescatar la salida standard de estos, si quieres me puedes enviar el archivo que no pudiste adjuntar a mi casilla de correo, esta es pbarrera@lintex.cl, gracias nuevamente, saludos.

Última edición por pkbza fecha: 12-01-2006 a las 12:24:44.
Responder Con Cita
  #5  
Antiguo 12-01-2006
Avatar de mg1821
mg1821 mg1821 is offline
Miembro
 
Registrado: may 2003
Ubicación: lima
Posts: 69
Poder: 21
mg1821 Va por buen camino
aqui esta el archivo completo, prefiero colocarlo asi para que este a la vista de todos. disculpas si esto no estaba permitido (el archivo era solo de 17k )

Starting an external application with Kylix
Here are three methods of invoking external applications. By Matthias Thoma.

Method 1: LibC.System function call
function system(Command: PChar): Integer;
The Libc.System function call is the most convenient way to start an external application. It simply executes the given argument command as shell command.
system is a blocking function, which means it will not return until the child process has terminated. The result value is -1 or 127 if an error occurred. The value 127 has the special meaning that execve (used within the system function - a more detailed description follows) failed.
On some shells you can add an ampersand (the "&" char) to the argument command. This will force the system function call to return immediately:

procedure PlayWave;
begin
if Libc.system('playwav ~/test.wav') = -1 then
begin
ShowMessage('Can''t play wav file');
end;
end;
Example 1.1: Play a wav file using system

You can determine if a shell is available by using nil as argument. If the result value is not zero, system was unable to invoke a shell.

procedure ShellAvail;
begin
if Libc.system(nil) <> 0 then
begin
ShowMessage('No shell available.');
end;
end;
Example 1.2: Determine if a shell is available

Method 2: popen
This method is extremely useful when you need to get the standard output of the external application. The popen function is declared as

function popen(const Command: PChar; Modes: PChar): PIOFile; cdecl;

It invokes the shell, runs the command, and creates a pipe. This demo simply displays the contents of the current directory within a memo.

var
Output: PIOFile;
line: PChar;
txt: string;
str: string;
StrLst: TStringList;
rb: integer;
const
BufferSize: Integer = 1000;
begin
SetLength(txt,0);
Output := popen('ls -l','r');
StrLst := TStringList.Create;
GetMem(Line,BufferSize);
StrLst.Add('Hallo');
if Assigned(output) then
begin
while FEOF(Output)=0 do
begin
rb := libc.fread(line,1,BufferSize,output);
SetLength(Txt,length(txt)+rb);
MemCpy(@txt[length(txt)-(rb-1)],line,rb);
while pos(#10,txt) > 0 do
begin
str := copy(txt,1,pos(#10,txt)-1);
StrLst.Add(str);
txt := copy(txt,pos(#10,txt)+1,length(txt));
end;
end;
end;
Memo1.Lines.AddStrings(StrLst);
StrLst.Free;
libc.pclose(output);
wait(nil);
FreeMem(Line,BufferSize);
end;

Method 3: Fork and Exec
Fork and Exec is how hardcore Linux and Unix programmers would create a child process. In fact, the previous functions are internally implemented using fork and exec.
function fork: __pid_t; cdecl;
The fork function makes a copy the parent process and therefore creates a new subprocess. Within the parent process the result value of fork is the Process ID (PID) of the subprocess or an error code. In the newly created subprocess the result value is zero.
Note: The function fork and the Kylix debugger do not seem to be 100% compatible currently. If you encounter problems and you are running the application within the IDE it is recommended that you disable the debugger.

{$APPTYPE CONSOLE}
uses
Libc;
procedure Forking;
var
pid: PID_T;
begin
pid := fork;
if pid = 0 then
begin
writeln('Hello. I am your new sub-process.');
writeln('Bye.');
halt;
end;
writeln('Hello. I am the parent process. I am going to wait some time...');
__sleep(3);
end;
begin
Forking;
writeln('Close parent process.');
writeln('Bye.');
end.
Example 3.1: Fork

As you see, fork copies the parent process. The child process starts to execute after the fork call. The differences between the parent process and the child process are only:
* The child has a different process identifier.
* The child has a different parent process.
* File locks are not inherited.
* Pending signals are not inherited.

Exec

Since we have now a new child process it is necessary to replace that process image with a new one:

function execve(PathName: PChar; const argv: PPChar; const envp: PPChar): Integer;
function execv(PathName: PChar; const argv: PPChar): Integer;

The execve function loads and executes PathName. The arguments are stored in argv and the environment is stored in envp.
execv performs the same actions as execve, except that the environment is taken from the "environ" setting.

program ForkExecDemo;
{$APPTYPE CONSOLE}
uses
Libc;
procedure ForkAndExec;
var
pid: PID_T;
parg: array[1..3] of PChar;
filetoplay: string;
begin
pid := fork;
if pid = 0 then
begin
filetoplay := 'test.wav';
parg[1] := 'playwave';
parg[2] := PChar(FileToPlay);
parg[3] := nil;
if execv('/usr/bin/playwave',PPChar(@parg[1])) = -1 then
begin
writeln('Something is wrong in the sub process.');
Halt;
end;
end;
writeln('Hello. I am the parent process. I am going to wait some time...');
__sleep(3);
end;
begin
ForkAndExec;
writeln('Close parent process.');
writeln('Bye.');
end.
Example 3.2: Fork and Exec

While this works great in console applications you may get problems in X applications because fork copies all the file descriptors. In such a case you'll have to close them within the child process. Example 3.3 illustrates this:

procedure ForkAndExec;
var
pid: PID_T;
Max: Integer;
I: Integer;
begin
pid := fork;
if pid = 0 then
begin
Max := sysconf(_SC_OPEN_MAX);
for i := (STDERR_FILENO+1) toMax do
begin
fcntl(i, F_SETFD, FD_CLOEXEC);
end;
[...]
end;
[...]
end;
Example 3.3: Closing the file descriptors

Sometimes you may want to let the parent process wait until the child process has been terminated. This can be done using the function waitpid. It is declared as:

function waitpid(__pid: pid_t; __stat_loc: PInteger; __options: Integer): pid_t; cdecl;
__pid: The process to wait for.
__stat_loc: The status of the terminated app. Can be nil.
__options: Zero,a flag or an combination of the flags WNOHANG and WUNTRACED. WNOHANG doesn't let the parent wait until the child has finished while WUNTRACED delivers status information not only from terminated applications but also from stopped ones. None of the flags are of interest for our purposes.
Example 3.4 illustrates the usage of the function WaitPid. It uses fork and execvp.

function StartApp(name: string; arguments: array of string): Integer;
var
pid: PID_T;
Max: Integer;
I: Integer;
parg: PPCharArray;
argnum: Integer;
begin
Result := -1;
pid := fork;
if pid = 0 then
begin
Max := sysconf(_SC_OPEN_MAX);
for i := (STDERR_FILENO+1) to Max do
begin
fcntl(i, F_SETFD, FD_CLOEXEC);
end;
argnum := High(Arguments) + 1;
GetMem(parg,(2 + argnum) * sizeof(PChar));
parg[0] := PChar(Name);
i := 0;
while i <= high(arguments) do
begin
inc(i);
parg[i] := PChar(arguments[i-1]);
end;
parg[i+1] := nil;
execvp(PChar(name),PPChar(@parg[0]));
halt;
end;
if pid > 0 then
begin
waitpid(pid,@Result,0);
end;
end;
Example 3.4: StartApp function
__________________
mg1821
Responder Con Cita
  #6  
Antiguo 13-01-2006
pkbza pkbza is offline
Miembro
 
Registrado: may 2004
Posts: 48
Poder: 0
pkbza Va por buen camino
Gracias, veré que puedo hacer con eso, saludos.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Capturar la salida de un comando dos. spab API de Windows 26 04-02-2011 13:05:08
Pedir consejo para elegir entorno de programación linux Casimiro Notevi Linux 29 29-06-2006 05:50:40
BD firebird en Linux Redhat 9 Choclito Firebird e Interbase 2 26-11-2004 10:57:23
Windwows(xp pro o 2003), Linux, Mac Quien ganará KORN Debates 13 19-09-2004 14:14:22
Usar Linux como Server . . . uper Linux 2 24-06-2004 20:07:18


La franja horaria es GMT +2. Ahora son las 09:04:16.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi