我想要解析/etc/passwd
文件来查明用户是否可以运行交互式 shell。
我知道文件每行的第 7 个字段/etc/passwd
告诉了 shell 的路径。但是您怎么说定义的 shell 是交互式的?
我正在用 python 解析这个文件,我可以实现逻辑,但我只是不知道如何找出如何识别交互式 shell。
PS.我想用python找出它。
答案1
我认为你有一个基本的误解:谈论一个你不能以交互方式运行但可以以非交互方式运行的 shell 就像谈论一辆你不能驾驶但可以用它来听收音机的汽车一样。
shell 的主要目的是以交互方式运行,它可以以非交互方式运行是可选的,而不是相反。
更接近于无法以交互方式运行但可以以非交互方式运行的 shell 的概念是一种无法以交互方式解释的解释型语言(尽管我现在没有想到一个真实的例子:最常见的解释型语言都可以运行交互式会话:Perl、Python、PHP,...)
如果你想了解用户允许通过 shell 登录,你可以使用此命令:
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"
(将命令user
中getent passwd user
的用户名替换)
在 Python 中你可以这样做:
#!/usr/bin/python
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")
else:
print(line.rstrip("\n").split(":")[6])
(user
在user = "user"
语句中用用户的用户名替换)
或者,按照 muru 的建议,最好使用模块pwd
:
#!/usr/bin/python
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")
else:
print(shell)
(user
在user = "user"
语句中用用户的用户名替换)
在上述所有例子中,如果用户/etc/passwd
条目的第七个字段是或/usr/sbin/nologin
,则/usr/bin/false
打印一条消息,提示用户不允许登录;否则打印用户的登录 shell。
但请记住无法通过 shell 登录并不意味着用户根本无法登录,并且可能存在其他伪 shell 或/usr/sbin/nologin
用于/bin/false
禁止用户登录。你也应该小心这些。
答案2
循环遍历文件,将每行拆分为字段,并检查 UID 大于 1000 的所有行的第 6 个字段是否不包含“no-login”
>>> 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
...
testuser:x:1001:1001:,,,:/home/testuser:/bin/bash
tester:x:1002:1002:TESTER,,,:/home/tester:/bin/bash
newUser:x:1003:1003::/home/newUser:
testUser:x:1004:1004::/home/testUser:
testuser2:x:1005:1005:asdf,asdf,asdf,asdf,asdf:/home/testuser2:/bin/bash
已设置 shell 的用户名可以使用该 shell 登录,例如xieerqi
has /bin/mksh
,而testUser
has /bin/bash
。其他用户未设置 shell,则默认为/bin/bash