2

I am trying to find the current logged in username from Java.

Process p;
try
{
    p = Runtime.getRuntime().exec("who -m");
    p.waitFor();
    BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));

    String line = "";
    while ((line = reader.readLine()) != null)
        System.out.println(line);
}
catch (Exception e)
{

}

The above code does not print any result. However if i remove -m option, it prints user name and other details. And also i tested with other options like -s, -u. It all works except -m. Does anyone has an idea why is it so?

Note: I am aware of

System.getProperty("user.name");

But that's not a solution in my case. I am calling a shell script in which "who -m" is used. So, I cannot use java classes.

Karthik Andhamil
  • 848
  • 1
  • 13
  • 22
  • 2
    did you try it on the command line? – jgr208 Sep 30 '14 at 14:47
  • My `who` man page says `who -m` displays "only hostname and user associated with stdin". If standard input has been changed, you might have problems. – ajb Sep 30 '14 at 15:09
  • @jgr208 - Yes. I did. It works on command line but not within Java environment. – Karthik Andhamil Sep 30 '14 at 15:26
  • @ajb - Yes. I understand that's the case. Do you have any suggestion to overcome this? – Karthik Andhamil Sep 30 '14 at 15:27
  • there may be no way around this depending on what is happening to the shell. if the shell is blown away you may be out of luck. – jgr208 Sep 30 '14 at 15:35
  • If you don't mind, I'd like to focus on the actual problem for a minute. What exactly is it that you are trying to do, and why do you feel that parsing the output of `who` is the way to go? Both the hostname and the current username can be determined programmatically (and more portably) from within your Java application. – thkala Sep 30 '14 at 15:46
  • You might want to have a look at this question: http://stackoverflow.com/q/473446/507519 – thkala Sep 30 '14 at 15:49
  • @KarthikAndhamil If you use `ProcessBuilder` and redirect standard input to `"/dev/tty"`, maybe it will work, but this is just a wild guess. And I think that using something besides `who -m` to find the information is a good idea. – ajb Sep 30 '14 at 15:51
  • @thkala - As I mentioned in my question, I am aware of that particular solution. But the problem is, I am calling a shell script in which there is a function that calls "who -m" command. And this shell script is accessed by different tools that are developed using different languages. It works everywhere except Java tool. So, I need to find a solution within shell script that would work with every other tool including Java. – Karthik Andhamil Sep 30 '14 at 15:52
  • so can you edit the shell script or not? – jgr208 Sep 30 '14 at 16:21
  • @jgr208 - Yes. I can edit the script for minimal change and the solution should work for other tools as well. – Karthik Andhamil Sep 30 '14 at 17:05
  • Please expand on other tools. well would changing the command be minimal change? – jgr208 Sep 30 '14 at 17:07

2 Answers2

2

The reason for what you are seeing is that the Java process launcher does not guarantee the existence of an associated TTY. Consider this example on the actual command line:

$ who -m
user   pts/8        2014-09-02 02:24
$ who -m </dev/null
$

Since the standard input is not associated with a terminal for the second who call, who cannot determine the associated user. Interestingly enough, redirecting stdin to /dev/tty does not appear to work either:

$ who -m </dev/tty
$

Quite honestly, unless determining the user associated with stdin is exactly what you are after, you should probably update your script to use hostname and e.g. id -un or whatever other means your shell interpretter may offer to determine the current user.


For those interested in the details, I did a little bit more digging for another answer of mine.

Community
  • 1
  • 1
thkala
  • 84,049
  • 23
  • 157
  • 201
0

From the man page for who:

"-m  only hostname and user associated with stdin"

I gather that this means the who command knows the current user based on a "who just hit the return key?" criteria. Given that you are running the command from the JVM, I would entirely expect something weird to happen.

If you're using a bash script, try this as a work around.

process=`ps | grep ps | cut -d ' ' -f2`
user=`who -u | grep $process | cut -d ' ' -f1`

Unfortunately I've never tried to make java and bash work togeather, sorry I cant be more helpful!

ConMan
  • 1,642
  • 1
  • 14
  • 22