FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Temas de Hoy |
|
Herramientas | Buscar en Tema | Desplegado |
#1
|
|||
|
|||
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. |
#2
|
||||
|
||||
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 |
#3
|
||||
|
||||
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 |
#4
|
|||
|
|||
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. |
#5
|
||||
|
||||
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 |
#6
|
|||
|
|||
Gracias, veré que puedo hacer con eso, saludos.
|
|
|
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 |
|