ValueError: need more than one value to unpack when parsing /etc/passwd

ValueError: need more than one value to unpack when parsing /etc/passwd

我创建了一个简单的应用程序,它打印 /etc/passwd 输出的可读信息,但在解析文件中的大多数条目后我收到一条错误消息:

Traceback (most recent call last):
  File "unpacking_args5.py", line 19, in <module>
    uname, *fields, homedir, sh = user_info
ValueError: need more than 1 values to unpack

代码如下:

import subprocess

# the return command output is a string because
# of universal_newlines set to True
output = subprocess.check_output(
            ['cat', '/etc/passwd'],
            universal_newlines = True
        )

# this command converts it into a list of user information on the system
output = output.split('\n')

# --------------------- If this is the value passed there's no error ---- #
# output = [
#     'ianhxc:x:1000:1000:ianHxc,,,:/home/ianhxc:/usr/bin/zsh'
# ]

for line in output:
    user_info = line.strip().split(":")
    uname, *fields, homedir, sh = user_info

    print('Uname: %s' % uname)
    print('Fields: %s' % fields)
    print('homedir: %s' % homedir)
    print('shell: %s' % (sh or 'None'))
    print('')

命令的输出如下:

Uname: root
Fields: ['x', '0', '0', 'root']
homedir: /root
shell: /bin/bash

Uname: daemon
Fields: ['x', '1', '1', 'daemon']
homedir: /usr/sbin
shell: /usr/sbin/nologin

# ... many successful entries omitted ...

Uname: mysql
Fields: ['x', '999', '999', '']
homedir: /home/mysql
shell: None

Traceback (most recent call last):
  File "unpacking_args5.py", line 19, in <module>
    uname, *fields, homedir, sh = user_info
ValueError: need more than 1 values to unpack

我认为这与使用“星号运算符”有关。

在错误点,user_info 没有足够的元素分配给 unamefieldshomedirsh。将该赋值语句放入 try/except 块中,并打印出 exceptuser_info 以便您可以找出是什么输入使其阻塞。

您的行中没有 : 冒号;拆分这些时,您只会得到 一个 元素。

可以是带有 # 注释的行,例如:

>>> line = '#\n'
>>> user_info = line.strip().split(":")
>>> user_info
['#']
>>> uname, *fields, homedir, sh = user_info
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: need more than 1 values to unpack

你可以跳过这些行;测试 user_info 列表的长度:

for line in output:
    user_info = line.strip().split(":")
    if len(user_info) < 3:
        continue  # not enough fields to be valid
    uname, *fields, homedir, sh = user_info
    # etc.

请注意,这里使用 subprocess 矫枉过正 ;你也可以直接阅读文件:

with open('/etc/passwd') as output:
    for line in output:
        user_info = line.strip().split(":")
        if len(user_info) < 3:
            continue  # not enough fields to be valid
        uname, *fields, homedir, sh = user_info
        # etc.