I want to parse /etc/passwd file to find out if the user can run interactive shell.

I know the 7th field in each line of /etc/passwd file tells the path of shell. But How do you say that, defined shell is interactive?

I am parsing this files in python, I can implement the logic, I just don't know the how to find out how to identify Interactive shell.

PS. I want to find it out using python.

  • Do you want to check if the shell can run interactively? otherwise the question is implementation dependent and ambiguous.. – heemayl Feb 1 '16 at 4:52
  • I didn't read the question like that before... If they can run a shell they can run it interactively. How do you run a shell "non-interactively" (script) without running it from an interactive shell? Unless you mean running a script from a desktop environment. – kos Feb 1 '16 at 4:53
  • @heemayl actually I am new to linux, I will appreciate if you explain what is Interactive shell and how do you identify one. – Kishor Pawar Feb 1 '16 at 4:54
  • 1
    Check this ..as you don't understand the difference it is probably wiser to either remove or rephrase the question.. – heemayl Feb 1 '16 at 4:56
  • 1
    Parse /etc/shells. – muru Feb 1 '16 at 5:17

I think you have a basic misconception: talking of a shell that you cannot run interactively but that you can run non-interactively is much like talking of a car that you can't drive but that you can use to listen to the radio.

The main purpose of a shell is running interactively, the fact that it can run non-interactively is the optional, not the other way around.

Closer to the concept of a shell that you cannot run interactively but that you can run non-interactively is an interpreted language which can't be interpreted interactively (though one real example is not occuring to me right now: the most common interpreted languages all can run interactive sessions: Perl, Python, PHP, ...)

That been said if you want to find out whether a user is allowed to login through a shell, you can use this command:

shell=$(getent passwd user | cut -d ':' -f 7); [ "$shell" = "/usr/sbin/nologin" -o "$shell" = "/bin/false" ] && printf 'User is not allowed to login\n' || printf '%s\n' "$shell"

(replace user in the getent passwd user command with the user's username)

In Python you could do:

user = "user"
with open("/etc/passwd") as file:
    for line in file:
        if line.split(":")[0] == user:
            if line.rstrip("\n").split(":")[6] in ["/usr/sbin/nologin", "/bin/false"]:
                print("User is not allowed to login")

(replace user in the user = "user" statement with the user's username)

Or, as suggested by muru, better using the pwd module:

from pwd import getpwnam

user = "user"
shell = getpwnam(user)[6]
if shell in ["/usr/sbin/nologin", "/bin/false"]:
    print("User is not allowed to login")

(replace user in the user = "user" statement with the user's username)

In all of the examples above if the seventh field of the user's /etc/passwd entry is either /usr/sbin/nologin or /usr/bin/false a message saying that the user is not allowed to login is printed; otherwise the user's login shell is printed.

But keep in mind that not being able to login through a shell doesn't mean the user is not allowed to login at all, and that there might be bogus shells other than /usr/sbin/nologin or /bin/false used to forbid the user's login. You should watch out for those too.

| improve this answer | |
  • Also, there's the pwd library: docs.python.org/3/library/pwd.html – muru Feb 1 '16 at 6:28
  • 1
    @muru Huh right, I forgot I was pasting from the terminal. And yeah looks better using in. Thanks. – kos Feb 1 '16 at 6:50

Loop through file splitting each line into fields and check if 6th field doesn't contain "no-login" for all the lines where UID is greater than 1000

>>> with open("/etc/passwd") as file:
...     for line in file:
...        if  int(line.split(":")[2])  > 1000  and not str(line.split(":")[6]).__contains__("nologin"):
...            print line





Usernames who have shell set can login with that shell, for instance xieerqi has /bin/mksh, while testUser has /bin/bash. Other users don't have shell set, which will default to /bin/bash

| improve this answer | |
  • you mean all shells are Interactive except with the no-login? – Kishor Pawar Feb 1 '16 at 5:22
  • Serg, i am afraid the question is pretty ambiguous and your answer is not properly directed too..its not your fault actually as the OP is not clear about differences among shell sessions.. – heemayl Feb 1 '16 at 5:23
  • heemayl exactly I am not clear about the shell concept. – Kishor Pawar Feb 1 '16 at 5:24
  • @KishorPawar All the common shells, such as bash, ksh, csh , dash - all those are interactive if you can type something with keyboard. If you are using them for running a script, that's non-interactive. That's different question though. If a user has a shell set in /etc/passwd that means they can login interactively and control system using keyboard. So every user who has some form of shell set up (or like some of my users - blank ) those will be able to login and work interactively – Sergiy Kolodyazhnyy Feb 1 '16 at 5:30
  • 1
    You can also use /bin/false to disable the shell for a user – Germar Feb 1 '16 at 5:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.