什么是用于验证Linux用户的正则表达式?


Answers:


12

用户名的一般规则是其长度必须少于32个字符。有效的用户名取决于您的分配。

在Debian中shadow-utils 4.1,有一个is_valid_name功能chkname.c

static bool is_valid_name (const char *name)
{
    /*
     * User/group names must match [a-z_][a-z0-9_-]*[$]
     */
    if (('\0' == *name) ||
        !((('a' <= *name) && ('z' >= *name)) || ('_' == *name))) {
        return false;
    }

    while ('\0' != *++name) {
        if (!(( ('a' <= *name) && ('z' >= *name) ) ||
              ( ('0' <= *name) && ('9' >= *name) ) ||
              ('_' == *name) ||
              ('-' == *name) ||
              ( ('$' == *name) && ('\0' == *(name + 1)) )
             )) {
            return false;
        }
    }

    return true;
}

并在之前检查了用户名的长度:

bool is_valid_user_name (const char *name)
{
    /*
     * User names are limited by whatever utmp can
     * handle.
     */
    if (strlen (name) > USER_NAME_MAX_LENGTH) {
        return false;
    }

    return is_valid_name (name);
}

15

useradd(8)手册页中

通常建议仅使用以小写字母或下划线开头,后跟小写字母,数字,下划线或破折号的用户名。它们可以以美元符号结尾。用正则表达式表示:[a-z _] [a-z0-9 _-] * [$]?

在Debian上,唯一的限制是用户名既不能以短划线('-')开头,也不能包含冒号(':')或空格(空格:'',行尾:'\ n',制表符:' \ t'等)。请注意,使用斜杠('/')可能会破坏用于定义用户主目录的默认算法。

用户名最多只能包含32个字符。

因此,有一个一般性建议。实际限制取决于实现/分发的细节。在基于Debian的系统上,显然没有非常严格的约束。实际上,我只是useradd '€'在Ubuntu盒子上试过了,就可以了。当然,这可能会破坏一些不希望使用这种不寻常用户名的应用程序。为避免此类问题,最好遵循一般建议。


12

很抱歉,这个问题已有将近4年的历史了,但它在Internet搜索结果中的排名很高,值得引起更多关注。

更准确的正则表达式是(是的,尽管有手册页,但我知道):

^[a-z_]([a-z0-9_-]{0,31}|[a-z0-9_-]{0,30}\$)$

希望这对某些搜索有所帮助。

分解:

  1. 它应该开始^)只用小写字母或下划线([a-z_])。这恰好占据1个字符。
  2. 然后,它应该是一个任一( ... )):
    1. 031个字符({0,31}的)字母数字下划线,和/或连字符[a-z0-9_-]),OR|
    2. 030以上的字符加上一个USD符号(\$)结尾,然后
  3. 超过此模式($)的字符不再。

对于那些不熟悉正则表达式模式的人,您可能会问为什么美元符号在2.2中反斜杠。但不是在3中。这是因为在大多数(全部?)正则表达式变体中,美元符号表示字符串(或行等)的结尾。根据所使用的引擎,如果它是实际字符串的一部分,则需要对其进行转义(我不认为我的正则表达式引擎的顶部不会使用反斜杠作为纯表达式的转义) 。

请注意,Debian和Ubuntu取消了对完全符合POSIX / shadow上游要求的用户名的一些限制(例如,我不知道此问题是否已解决,但他们允许用户名以数字开头-实际上是导致此问题的原因错误)。如果您想保证跨平台,我建议您使用上面的正则表达式模式,而不是通过/未通过Debian,Ubuntu等检查的方法。


好答案。也可以轻松地在Java中使用java.util.regex.Pattern.matches("^[a-z_]([a-z0-9_-]{0,31}|[a-z0-9_-]{0,30}\\$)$", user);
dokaspar,

应该[abcdefghijklmnopqrstuvwxyz]改为[a-z][a-z]在许多正则表达式引擎中,它们还匹配,​​例如éœ甚至有时匹配多字符排序元素(例如dsz在匈牙利语言环境中)。
斯特凡Chazelas

Linux用户名不接受Unicode(除非已将它们明确配置为破坏POSIX合规性-1 2)。该检查应在正则表达式之外进行,因为它是输入/环境/本地化验证,而不是字符串验证。此外,我很想听听执行此操作的正则表达式引擎的示例。我知道所有与ASCII匹配的代码,并且必须支持Unicode(如果支持)。
布伦特·桑纳
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.