Running “who am i” in a single command with sudo d

2019-09-06 19:29发布

I am trying to run "who am i" command in a single line in the following way and it returns nothing.

echo $password | sudo -u user -S who am i

Even logname command doesn't work in this way.

echo $password | sudo -u user -S logname

Can anyone please help?

1条回答
够拽才男人
2楼-- · 2019-09-06 20:06

When who is invoked with two arguments, the -m flag is activated. From the manual page:

-m
    only hostname and user associated with stdin

In your case, the standard input is a pipe, rather than a terminal, and who (or logname) cannot determine the associated user. Consider this shell command snippet:

$ who am i
user   pts/11       2014-09-04 00:15
$ logname
user
$ echo | who am i
$ echo | logname
logname: no login name
$ 

From the GNU Coreutils who.c source:

if (my_line_only)
  {
    ttyname_b = ttyname (STDIN_FILENO);
    if (!ttyname_b)
      return;
    if (STRNCMP_LIT (ttyname_b, DEV_DIR_WITH_TRAILING_SLASH) == 0)
      ttyname_b += DEV_DIR_LEN; /* Discard /dev/ prefix.  */
  }

Since ttyname() returns NULL on errors, such as the file descriptor not corresponding to a terminal (ENOTTY), who -m will return immediately when stdin is a pipe.

As for logname, its proper behavior is to return the string that would have been returned by the getlogin() function. Unfortunately, the bug section of the getlogin() manual page is quite clear:

Note that glibc does not follow the POSIX specification and uses stdin instead of /dev/tty. A bug. (Other recent systems, like SunOS 5.8 and HP-UX 11.11 and FreeBSD 4.8 all return the login name also when stdin is redirected.)

Bottom line: you should probably update your code to use hostname and e.g. id -un or whatever other means your shell interpretter may offer to determine the current user. who -m and its friends are not very predictable - quite honestly the output of who, much like ls, has the distinct feel of being intended for humans, rather than machines.

查看更多
登录 后发表回答