Can anyone explain this behavior of clojure.java.shell/sh ?

483 views
Skip to first unread message

Andy Fingerhut

unread,
Nov 9, 2012, 8:26:57 PM11/9/12
to clojure
This issue may be specific to Linux, or even to a particular version of Linux that I am using (Ubuntu 11.10 32-bit desktop), although I doubt it is. If others try this out, I'd be curious to know what your results are, especially if you know why it is happening, and how it can be fixed.

First, some behavior from a bash window on Ubuntu 11.10:

% echo hi
hi
% xdg-open http://www.google.com
%

After pressing return for the xdg-open command above, my browser opens a tab to Google's home page. Back in the shell window, the next prompt appears immediately, even though the browser is still running and open to that page. That is what I expect to happen.

However, if I do the following commands inside of a Clojure REPL (tested Clojure 1.4 and 1.5-beta1 so far):

% rlwrap java -cp ~/lein/clojure-1.4.0/lib/clojure-1.4.0.jar clojure.main
Clojure 1.4.0
user=> (require '[clojure.java.shell :as sh])
nil
user=> (sh/sh "echo" "hi")
{:exit 0, :out "hi\n", :err ""}
user=> (sh/sh "xdg-open" "http://www.google.com")

The invocation of echo returns immediately, printing the result and the next REPL prompt. But when I invoke xdg-open, while the browser window appears and goes to the Google home page, back in the bash window I see no return value and no new REPL prompt.

If I quit the browser, then back in the bash window I finally see the return value and a REPL prompt, as shown below:

{:exit 0, :out "", :err ""}
user=>


What I'm wishing would happen is for the return value and REPL prompt to appear very soon after pressing return when invoking xdg-open with clojure.java.shell/sh.

I added some debug print messages to a local copy of clojure.java.shell/sh, and it is stopping when waiting for the evaluation of either @out or @err in the final line of the function.

If I do the same commands above on Mac OS X, with "open" instead of "xdg-open", it all works as I expect.

Any clues?

Thanks,
Andy

Ravindra Jaju

unread,
Nov 9, 2012, 11:14:21 PM11/9/12
to clo...@googlegroups.com
Don't have access right now to check, but guessing that xdg-open waits for the child process to exit.
Try detaching/backgrounding? Not sure how you'd do that with the "sh" function though.

Naively, wrap in (future ...)?

--
jaju


--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Michael Gardner

unread,
Nov 10, 2012, 12:51:49 AM11/10/12
to clo...@googlegroups.com
I can't duplicate your results on my Debian wheezy box (Clojure 1.4, openjdk 1.6.0_24, xdg-open 1.1.0 rc1); the call to (sh "xdg-open" …) returns immediately. The only possibilities I can think of are that your version of xdg-open blocks when run from a non-interactive shell, or that your version of Java somehow handles subprocesses differently.

The first possibility should be easy to test. And you should be able to test the second by writing your own shell script that forks and then exits (at least, I assume that's what xdg-open is doing).

Leo Noordhuizen

unread,
Nov 10, 2012, 7:19:09 AM11/10/12
to clo...@googlegroups.com
I tried this and in the repl the propmt appears instantaneous again so this seems to work fine here.

Aaron Cohen

unread,
Nov 10, 2012, 3:26:26 PM11/10/12
to clo...@googlegroups.com
I'm pretty sure xdg-open ends up being a thin wrapper that delegates
to your desktop environment's open program (gnome-open, kde-open,
xce-open, etc)
so probably that is where the difference lies.

--Aaron

Andy Fingerhut

unread,
Nov 10, 2012, 5:27:53 PM11/10/12
to clo...@googlegroups.com
There must be a difference between these other folks's environments and mine, given the different behavior.

What I find so odd is that it hangs when invoked via clojure.java.shell/sh from within the REPL, but returns immediately with another prompt when run from bash. I've even copied the xdg-open on the system exhibiting this problem, because it is a shell script, and added debug statements to it to print out environment variables. They are nearly identical when invoked from bash vs. when invoked from in the REPL, except for the value of LD_LIBRARY_PATH. I thought that might cause the different behavior, but after tweaking things to make them the same I still saw the hang from the REPL.

I'll try creating another user on that system to see if it happens there, but if most people don't see this behavior, that is a good thing for when/if the patch for CLJ-896 is committed, which is the reason I was testing this and finding the odd behavior.

http://dev.clojure.org/jira/browse/CLJ-896

Thanks,
Andy

Aaron Cohen

unread,
Nov 10, 2012, 6:07:10 PM11/10/12
to clo...@googlegroups.com
I would check what "open" program it is that eventually gets used on
your system. I imagine whichever one it is is trying to make your life
easier by changing its behavior when invoke interactively vs in a
script.

once you find which one it is, you may be able to suppress that helpfulness.

--Aaron
Reply all
Reply to author
Forward
0 new messages