When invoking shell scripts from Erlang, I usually need their exit status (0 or something else), so I run them using this function:
%% in module util os_cmd_exitstatus(Action, Cmd) -> ?debug("~ts starting... Shell command: ~ts", [Action, Cmd]), try erlang:open_port({spawn, Cmd}, [exit_status, stderr_to_stdout]) of Port -> os_cmd_exitstatus_loop(Action, Port) catch _:Reason -> case Reason of badarg -> Message = "Bad input arguments"; system_limit -> Message = "All available ports in the Erlang emulator are in use"; _ -> Message = file:format_error(Reason) end, ?error("~ts: shell command error: ~ts", [Action, Message]), error end. os_cmd_exitstatus_loop(Action, Port) -> receive {Port, {data, Data}} -> ?debug("~ts... Shell output: ~ts", [Action, Data]), os_cmd_exitstatus_loop(Action, Port); {Port, {exit_status, 0}} -> ?info("~ts finished successfully", [Action]), ok; {Port, {exit_status, Status}} -> ?error("~ts failed with exit status ~p", [Action, Status]), error; {'EXIT', Port, Reason} -> ?error("~ts failed with port exit: reason ~ts", [Action, file:format_error(Reason)]), error end.
This worked fine until I used this to run a script that drops the program and exits:
#!/bin/sh FILENAME=$1 eog $FILENAME & exit 0
(There are still a lot of arguments in the actual usecase, and some are massaged before they are passed to the program). When launched from the terminal, it displays an image and immediately exits as expected.
But work from Erlang, it is not. In the log file, I see that it starts normally:
22/Mar/2011 13:38:30.518 Debug: Starting player starting... Shell command: /home/aromanov/workspace/gmcontroller/scripts.dummy/image/show-image.sh /home/aromanov/workspace/media/images/9e89471e-eb0b-43f8-8c12-97bbe598e7f7.png
and the eog window will appear. But I do not get
22/Mar/2011 13:47:14.709 Info: Starting player finished successfully
until the eog process is eog (with kill or just closing the window), which is not suitable for my requirements. Why is there a difference in behavior? Is there any way to fix this?