id -u $ var fornece a mesma saída se $ var tiver um valor ou não

2

Estou escrevendo um script para configurar novas instalações do Debian, encontrando a melhor solução para confirmar que um usuário existe no script, a melhor maneira que encontrei me dá uma saída diferente.

PROBLEMA:

id -u $var e id -u $varsome fornecem o mesmo resultado, embora     var tem um valor (o nome de usuário) e varsome não tem valor

[19:49:24][username] ~ ~↓↓$↓↓ var='whoami'
[19:53:38][username] ~ ~↓↓$↓↓ id -u $var
1000
[19:53:42][username] ~ ~↓↓$↓↓ echo $?
0
[19:53:49][username] ~ ~↓↓$↓↓ id -u $varsome
1000
[19:09:56][username] ~ ~↓↓$↓↓ echo $?
0
[20:10:18][username] ~ ~↓↓$↓↓ bash --version
GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2016 Free Software Foundation, Inc.
Licens GPLv3+: GNU GPL version 3 eller senere <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
[20:27:08][username] ~ ~↓↓$↓↓ cat /etc/os-release 
PRETTY_NAME="Debian GNU/Linux 9 (stretch)"
NAME="Debian GNU/Linux"
VERSION_ID="9"
VERSION="9 (stretch)"
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

Eu recebi o comando desta pergunta em stackoverflow: Verifique se existe um usuário

PERGUNTAS:

  • O que está acontecendo aqui?
  • Existe uma maneira melhor de você encontrar para verificar se um usuário existe em um script?
  • Os ponteiros no script são bem-vindos
por somethingSomething 14.08.2018 / 22:37

2 respostas

9

Como a expansão da variável não foi citada, a palavra vazia resultante de $varsome sendo expandida é removida completamente.

Vamos criar uma função que imprima o número de argumentos obtidos e compare o caso citado e não citado:

$ args() { echo "got $# arguments"; }
$ var=""
$ args $var
got 0 arguments    
$ args "$var"
got 1 arguments

O mesmo acontece no seu caso com id : id -u $var é exatamente o mesmo que id -u quando var está vazio. Como id não vê um nome de usuário, ele por padrão imprime as informações do usuário atual.

Se você citar "$var" , o resultado será diferente:

$ var=""
$ id -u "$var"
id: ‘’: no such user

Com isso corrigido, você pode usar id para descobrir se um usuário existe. (Não precisamos das saídas aqui, portanto, redirecione-as.)

check_user() { 
    if id -u "$1" >/dev/null 2>&1; then
        echo "user '$1' exists"
    else
        echo "user '$1' does not exist"
    fi
}
check_user root
check_user asdfghjkl

Isso imprimiria user 'root' exists e user 'asdfghjkl' does not exist .

Isso é um pouco do inverso dos problemas usuais que surgem da divisão inesperada de palavras de variáveis não citadas. Mas a questão básica é a mesma e fixada por meio que as respostas aqui dizem: sempre cite as expansões variáveis (a menos que você saiba que quer o comportamento não cotado).

Veja:

por 14.08.2018 / 23:19
1

O comando id -u fornecerá o ID do usuário atual. O comando id -u user fornecerá o ID desse usuário.

Agora, no seu exemplo, você usa

var='whoami'
id -u $var

O comando whoami retorna o usuário atual. Portanto, id -u current_user retornará o id do usuário atual e id -u também retornará o id do usuário atual.

Editar

Observe que os backticks estão obsoletos e recomenda-se escrever $(whoami) , por exemplo:

var=$(whoami)
id -u $var
    
por 14.08.2018 / 23:01