Run a command and capture output
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
character(len=*), | intent(in) | :: | command | |||
character(len=*), | intent(out) | :: | output | |||
integer, | intent(out) | :: | exit_code | |||
integer, | intent(in), | optional | :: | timeout |
subroutine sys_run_command(command, output, exit_code, timeout) character(len=*), intent(in) :: command character(len=*), intent(out) :: output integer, intent(out) :: exit_code integer, intent(in), optional :: timeout character(len=1024) :: full_command, temp_file integer :: unit, iostat ! Initialize output and exit_code output = "" exit_code = -1 ! Check for empty or invalid command if (len_trim(command) == 0) then output = "Error: Empty command" exit_code = 127 ! Command not found return end if temp_file = create_temp_file('sys_cmd_output', '.tmp') ! Build the command carefully, wrapping in shell to handle edge cases if (get_os_type() == OS_WINDOWS) then if (present(timeout)) then ! Windows doesn't have a simple timeout command full_command = 'cmd /c "'//trim(command)//' > "'//trim(escape_shell_arg(temp_file))//'" 2>&1"' else full_command = 'cmd /c "'//trim(command)//' > "'//trim(escape_shell_arg(temp_file))//'" 2>&1"' end if else if (present(timeout)) then write (full_command, '(A,I0,A)') 'sh -c ''timeout ', timeout, ' '//trim(command)// & ' > "'//trim(escape_shell_arg(temp_file))//'" 2>&1''' else full_command = 'sh -c '''//trim(command)//' > "'//trim(escape_shell_arg(temp_file))//'" 2>&1''' end if end if ! Use cmdstat to catch invalid command errors call execute_command_line(full_command, exitstat=exit_code, cmdstat=iostat) ! Handle command execution errors if (iostat /= 0) then exit_code = 127 ! Command not found output = "Command execution failed" call sys_remove_file(temp_file) return end if output = "" open (newunit=unit, file=temp_file, status='old', iostat=iostat) if (iostat == 0) then read (unit, '(A)', iostat=iostat) output close (unit) end if call sys_remove_file(temp_file) end subroutine sys_run_command