1
votes

Why lein repl blocks STDERR. I run lein repl without project and also lein repl or lein run with a project and having problems printing to STDERR. For example when connecting to NREPL (different terminal tab) and running:

(.println System/err "something")

I can see nothing printed in the launching terminal window - only in the repl. How to get STDERR to print in both as it is used for SYSTEMD logging. I use newest Leiningen and project is generated wit the app template.

1
odd, here's what I get: lein repl user=> (.println System/err "bubu") bubu nil - Jochen Bedersdorfer
Please add your version of clojure, leiningen, and the contents of your ~/.lein/profiles.clj. FWIW my combination of those things prints fine with the snippet you posted. - bfabry
Oh, so your real question is about writing to the journal? This is a lot clearer now. I'd start reading through github.com/clojure-emacs/cider-nrepl/blob/master/src/cider/…, or whatever middleware is actually in use in your stack. - Charles Duffy

1 Answers

0
votes

lein repl does no such thing. You can test this yourself:

# stop our individual writes from overlapping
with_lock() { exec {lock_fd}>>./tty_write_lock; flock "$lock_fd"; "$@"; exec {lock_fd}>&-; } 

lein repl 3>&2 \
           > >(while IFS= read -r line; do with_lock printf 'O:<%q>\n' "$line" >&3; done) \
          2> >(while IFS= read -r line; do with_lock printf 'E:[%q]\n' "$line" >&3; done) \
          3>&- <<'EOF'
(.println System/err "something on stderr")
(.println System/out "something on stdout")
EOF

...which contains, among other output:

O:<$'user=> (.println System/err "something on stderr")\E[50G\E[8G\E[51G'>
E:[something\ on\ stderr]
O:<nil>
O:<$'user=> (.println System/out "something on stdout")\E[50G\E[8G\E[51G'>
O:<something\ on\ stdout>
O:<nil>

As you can see, something on stdout is inside O:<...>, as created by the process substitution handling stdout; whereas something on stderr is inside E:[...], as created by the process substitution handling stderr.


To look at it a different way:

{ strace -f -e write lein repl 2>&1 | egrep 'write[(][12],'; } <<'EOF'
(.println System/err "something on stderr")
(.println System/out "something on stdout")
EOF

...includes among its output the following syscalls:

[pid 10467] write(2, "something on stderr", 19) = 19
[pid 10467] write(1, "something on stdout", 19) = 19

...as you can see, the stderr one is correctly written to FD 2, whereas the stdout one is correctly written to FD 1.