Por que isso acontece?
O motivo pelo qual ele falha é porque os itens com $ iniciais são tratados como variáveis e não são citados quando você os passa para useradd .
As porções ... , ... e $b... do seu hash são tratadas como variáveis. Naturalmente, a falha é com os shell - shells executam uma expansão variável (a menos que eles estejam entre aspas simples) antes que algo seja executado. E como essas 3 variáveis não existem em seu ambiente, elas desaparecem da string que você passa para useradd .
Exemplo prático:
Vamos ver o comando real executado após o shell terminar de executar todas as expansões e substituições necessárias e passar isso para execve() system call. Comparar:
$ strace -e execve useradd -p $abra$cadabra newuser
execve("/usr/sbin/useradd", ["useradd", "-p", "newuser"], [/* 82 vars */]) = 0
$ strace -e trace=execve useradd -p '$abra$cadabra' newuser
execve("/usr/sbin/useradd", ["useradd", "-p", "$abra$cadabra", "newuser"], [/* 82 vars */]) = 0
No primeiro exemplo $abra$cadabra (que é onde o hash iria) desaparece do comando que realmente é executado pelo sistema. Por outro lado, o único citado $abra$cadabra no segundo exemplo aparece na lista de argumentos transmitidos para execve() .
Em outras palavras, você gerou o hash correto, mas o shell passa uma coisa completamente diferente para useradd como argumento, que é o comando que o sistema executa. De fato, vamos pegar seu hash por exemplo e comparar dois casos de cotação e não-citação:
$ strace -e execve echo FuuSdKgVke$bc8doOVGZhzomoeafvcQnpYhAxfR4aWdAuYvbxSHw6ZCFZ4NC5j9C762kmvs4Pc66bv4.LYTfrlknm5cWx65g
execve("/bin/echo", ["echo", "FuuSdKgVke.LYTfrlknm5cWx65g"], [/* 82 vars */]) = 0
FuuSdKgVke.LYTfrlknm5cWx65g
+++ exited with 0 +++
Observe que o que o sistema realmente vê após o shell é processado, as variáveis são FuuSdKgVke.LYTfrlknm5cWx65g . Mas ele verá o hash correto se você citá-lo:
$ strace -e execve echo 'FuuSdKgVke$bc8doOVGZhzomoeafvcQnpYhAxfR4aWdAuYvbxSHw6ZCFZ4NC5j9C762kmvs4Pc66bv4.LYTfrlknm5cWx65g'
execve("/bin/echo", ["echo", "FuuSdKgVke$bc8doOVGZhzomoeaf"...], [/* 82 vars */]) = 0
O que pode ser feito? O que funciona?
No entanto, o subshell funciona porque não há substituição ocorrendo - não há variáveis. E as citações também funcionam pelo mesmo motivo.
Aqui estão alguns métodos:
-
Substituição de comandos:
$ sudo -p ">" useradd -m -s /bin/bash -p $(mkpasswd --hash=SHA-512 "123" ) newusr
>
$ su newusr
Password:
newusr@ubuntu1604:/home/admin$
-
Aspas simples (observe que apareci o hash real porque é muito longo e não cabe na formatação):
$ sudo -p ">" mkpasswd --hash=SHA-512 "112"
>
GVhvDY$vhw89D2X0bd2REQWE
$ sudo -p ">" useradd -m -s /bin/sh -p 'GVhvDY$vhw89D2X0bd2REQWE' newusr2
>
$ su newusr2
Password:
$ echo $USER
newusr2
-
Pegue a saída do mkpasswd ' stdout stream e passe-a via xargs com -I flag:
$ mkpasswd -m sha-512 'password1' | sudo -p '>' xargs -I % useradd -p % newuser1
-
Anexe o \ a cada $ (que o OP descobriu na sua resposta ). Scriptable, também, como por comentário de George . / p>
$ useradd -m -s /bin/bash -p $6$5AfGzrQ9u$r6Q7Vt6h8f2rr4TuW4ZA22m6/eoQh9ciwUuMDtVBX31tR3Tb0o9EB1eBdZ2L9mvT.pX3dIEfxipMoQ0LtTR3V1 newuser