# How to get shell echo in Prolog variables

**URL:** https://swi-prolog.discourse.group/t/how-to-get-shell-echo-in-prolog-variables/6547
**Category:** General
**Tags:** how-to
**Created:** [May 14, 2023, 11:33am UTC](https://swi-prolog.discourse.group/t/how-to-get-shell-echo-in-prolog-variables/6547 "2023-05-14T11:33:57Z")
**Posts on this page:** 1
**Showing post:** 15

<div class="post-metadata">

### Author: ![brebs](https://avatars.discourse-cdn.com/v4/letter/b/e9c0ed/32.png) [@brebs](https://swi-prolog.discourse.group/u/brebs)
#### Post date: [May 15, 2023, 2:11pm UTC](https://swi-prolog.discourse.group/t/how-to-get-shell-echo-in-prolog-variables/6547/15 "2023-05-15T14:11:47Z")

</div>

This uses a thread, to prevent hanging:

```prolog
run_sh_command(StrCmd, OutputLines, ErrorLines, ExitCode) :-
    run_command([sh, '-ce', StrCmd], OutputLines, ErrorLines, ExitCode).

run_command(LstCmd, OutputLines, ErrorLines, ExitCode) :-
    LstCmd = [ExeName|Args],
    setup_call_cleanup(
        message_queue_create(ErrorQueue),
        setup_call_cleanup(
            process_create(
                path(ExeName), Args, [
                    process(PID),
                    stdout(pipe(OutputStream)),
                    stderr(pipe(ErrorStream))
                ]   
            ),
            ( thread_create(
                    ( read_stream_lines(ErrorStream, ErrorLines),
                        thread_send_message(ErrorQueue, ErrorLines)
                    ),
                    ThreadId
                ),
                read_stream_lines(OutputStream, OutputLines),
                process_wait(PID, ExitCode),
                thread_join(ThreadId),
                thread_get_message(ErrorQueue, ErrorLines)
            ),  
            ( close(OutputStream),
                close(ErrorStream)
            )   
        ),
        message_queue_destroy(ErrorQueue)
    ). 

read_stream_lines(Stream, Lines) :-
    read_line_to_codes(Stream, Line1),
    read_stream_lines_(Line1, Stream, Lines).

read_stream_lines_(end_of_file, _, Lines) :-
    !,
    Lines = [].
read_stream_lines_(Codes, Stream, [Line|Lines]) :-
    atom_codes(Line, Codes),
    read_line_to_codes(Stream, Line2),
    read_stream_lines_(Line2, Stream, Lines).

```

---

_[View the full topic](https://swi-prolog.discourse.group/t/how-to-get-shell-echo-in-prolog-variables/6547)._
