Author: Ladislav Slezak < lslezak@suse.cz>
Changes:
If you need to run program and display progress of its work you can not use target agent, because it waits until subprocess is finished.
Background agent returns result of execution just after subprocess is started and YCP code can continue. Agent stores data from STDOUT until they are read from YCP, which should parse data and refresh status in dialog.
When input buffer in background agent reaches defined value subprocess is stopped until buffer is read. Default buffer size is 500 lines for STDOUT and 200 lines for STDERR output (see .buffer_size or .buffer_size_err paths).
STDERR output can be also read, use .run_output_err command to also store error messages.
Outputs are read by character so it is possible to read output which is not terminated by the new line character. This is usefull if the subprocess uses prompt with. Use .buffer or .buffer_err subpaths for direct access to the internal line buffer. Use this feature carefully - input buffers are cleared after reading!
Background agent has these limitations:
Backround agent doesn't use virtual terminals, some programs buffer output when they detect no terminal device. In this case use option to disable buffering (e.g. grep --line-buffered).
Background agent uses .background root path, subpath determines command.
Path name | Paramenters | Result type | Description |
lines | none | integer | total number of stdout lines produced by subprocess |
newlines | none | integer | number of new stdout lines since last reading |
lines_err | none | integer | total number of stderr lines produced by subprocess |
newlines_err | none | integer | number of new stderr lines since last reading |
store | none | boolean | true if subprocess was started by run_output or run_output_errcommand |
isrunning | none | boolean | true if subprocess is running |
status | none | integer | subprocess exit status |
newout | none | list of strings | return stdout output since last reading |
newerr | none | list of strings | return stderr output since last reading |
output_open | none | boolean | true if stdout pipe from subprocess is open |
output_open_err | none | boolean | true if stderr pipe from subprocess is open |
buffer_size | none | integer | the size of stdout input buffer (number of lines) |
buffer_size_err | none | integer | the size of stderr input buffer (number of lines) |
buffer | none | string | read the internal stdout buffer, (note: buffer is cleared after reading!) |
buffer_err | none | string | read the internal stderr buffer (note: buffer is cleared after reading!) |
Example: SCR::Read(.background.newlines) -> 5
Note: if isrunning is false and output_open or output_open_err is true then subprocess exited, but some data are available in the buffer. Isrunning can be used for example to check whether program is running before sending a signal, output_open and newlines are used in loop tests.
Path name | Paramenters | Result type | Description |
run | string command | boolean | start subprocess, do not store output from STDOUT or STDERR, only count number of lines |
run_output | string command | boolean | start subprocess, store output from STDOUT, count output from STDERR. On success returns true. |
run_output_err | string command | boolean | start subprocess, store output from STDOUT and STDERR. On success returns true. |
kill | nil | boolean | kill subprocess with signal SIGTERM, then with SIGKILL signal, on success returns true |
Example: SCR::Execute(.background.run_output, "/bin/rpm -qa") -> true
Path name | Paramenters | Result type | Description |
buffer_size | integer lines | boolean | Set maximum number of stored lines (input buffer size) for STDOUT. When this limit is reached subprocess will be stopped until new lines are read. Parameter lines has to be greater than 0. Returns true if new value was set. |
buffer_size_err | integer lines | boolean | Same as buffer_size, but for STDERR output. |
stdin | string input | integer | Write input string to STDIN of the process. Input string can contain multiple lines. Returns number of the written characters. Don't forget to append the new line character at the end of the string, usually it is required. |
Example: Set STDOUT buffer size to 100 lines: SCR::Write(.background.buffer_size, 100) -> true
Here is YCP code skeleton:
SCR::Read(.background.run_output, "command with parameters"); while(SCR::Read(.background.output_open) || (SCR::Read(.background.newlines) > 0)) { list script_out = SCR::Read(.background.newout); /* parse lines in script_out and update progress in dialog accordingly */ while (SCR::Read(.background.newlines) == 0 && SCR::Read(.background.output_open)) { sleep(wait_time); symbol ret = UI::PollInput(); /* check if abort button was pressed */ } }
You can try example ag_background_example.ycp or YaST2 Backup module which uses background agent too.