Toolkits > SampleShellSource 1.1.0 > sample > TestShellSourceOutputAttributes.spl
This sample application ingests valid and invalid shell commands from a text file into tuples containing additional attributes, executes the commands with a ShellSource operator that illustrates how output attributes are copied from input attributes with the same name and type, and writes STDOUT, STDERR, and exit status from each command into files.
composite TestShellSourceOutputAttributes { param expression<rstring> $commandFile: dataDirectory() + "/commands.txt"; type CommandType = float64 commandTimestamp, int64 commandNumber, rstring command; OutputType = float64 commandTimestamp, int64 commandNumber, rstring command, int64 outputLineNumber, int64 outputLineLength, rstring outputLine; ErrorType = float64 commandTimestamp, int64 commandNumber, rstring command, rstring errorLine; StatusType = float64 commandTimestamp, int64 commandNumber, rstring command, int32 exitCode, rstring exitReason, list<uint64> counters ; graph // create a stream of shell commands for the ShellSource operators below to consume stream<CommandType> CommandStream as Out = FileSource() { param file: $commandFile; format: line; output Out: commandTimestamp = getTimestampInSecs(), commandNumber = TupleNumber(); } () as DebugCommandStream = FileSink(CommandStream) { param file: "debug.TestShellSourceOutputAttributes.CommandStream.out"; format: txt; hasDelayField: true; flush: 1u; writePunctuations: true; } // execute a stream of shell commands and produce tuples from the lines they write to STDOUT and STDERR, plus a status tuple with the commands' exit codes ( stream<OutputType> OutputStream ; stream<ErrorType> ErrorStream ; stream<StatusType> StatusStream ) = ShellSource(CommandStream) { logic state: { mutable int64 lineCounter = 0l; } param commandAttribute: command; stdoutAttribute: "outputLine"; stderrAttribute: "errorLine"; abortOnError: true; output OutputStream: outputLineNumber = ++lineCounter, outputLineLength = (int64)length(stdoutLine()), outputLine = stdoutLine(); StatusStream: exitCode = exitCode(), exitReason = exitReason(), counters = lineCounters(); } () as DebugOutputStream = FileSink(OutputStream) { param file: "debug.TestShellSourceOutputAttributes.OutputStream.out"; format: txt; hasDelayField: true; flush: 1u; writePunctuations: true; } () as DebugErrorStream = FileSink(ErrorStream) { param file: "debug.TestShellSourceOutputAttributes.ErrorStream.out"; format: txt; hasDelayField: true; flush: 1u; writePunctuations: true; } () as DebugStatusStream = FileSink(StatusStream) { param file: "debug.TestShellSourceOutputAttributes.StatusStream.out"; format: txt; hasDelayField: true; flush: 1u; writePunctuations: true; } // log STDERR lines to Streams application trace () as LogErrorStream = Custom(ErrorStream) { logic onTuple ErrorStream: { appTrc(Trace.info, "STDERR from command '" + command + "': " + errorLine); } } }