Encontre o proprietário de um diretório ou arquivo, mas retorne apenas isso e nada mais

62

Estou procurando um comando que retorne o proprietário de um diretório e somente isso - como uma expressão regular que analisa o ls -latcomando ou algo semelhante? Eu quero usar o resultado em outro script.

Jason
fonte

Respostas:

102

stat do GNU coreutils pode fazer isso:

stat -c '%U' /path/of/file/or/directory

Infelizmente, existem várias versões state não há muita consistência em sua sintaxe. Por exemplo, no FreeBSD, seria

stat -f '%Su' /path/of/file/or/directory

Se a portabilidade é uma preocupação, você provavelmente está melhor usando a sugestão de Gilles de combinar lse awk. Ele precisa iniciar dois processos em vez de um, mas tem a vantagem de usar apenas a funcionalidade padrão do POSIX:

ls -ld /path/of/file/or/directory | awk '{print $3}'
cjm
fonte
2
stat -c% U / caminho, se a brevidade for um bônus.
tsvallender
1
Isso pressupõe o estatuto GNU, que não é o caso em sistemas Linux mais antigos (mesmo em sistemas mais recentes, seria cauteloso, pode haver um diferente stat(um padrão para todo o site) em /usr/local/binalgum lugar da casa do usuário) e raramente está disponível em outros departamentos.
Gilles 'SO- stop be evil'
1
stat -c %Utem a vantagem de também trabalhar com o BusyBox , se o statcomando estiver compilado.
Gilles 'SO- stop be evil'
1
Nice, o último exemplo (ls) funciona tanto em Unix / OSX e Linux
kenorb
1
Observe que ls imprimirá o uid se não houver um usuário local que corresponda ao proprietário (ou seja, em um compartilhamento de rede), mas stat -c '%U' DIRimprimirá UNKNOWN, o que é menos útil ou mais apropriado, dependendo de como você o vê.
basic6
18

Analisar a saída de lsraramente é uma boa ideia , mas obter os primeiros campos é uma exceção, pois na verdade funciona em todos os departamentos "tradicionais" (não funciona em plataformas como algumas implementações do Windows que permitem espaços nos nomes de usuário).

ls -ld /path/to/directory | awk 'NR==1 {print $3}'

Outra opção é usar um statcomando, mas o problema com stato shell é que existem vários comandos com sintaxe diferente; portanto, statem um shell, o script não é portável (mesmo em instalações Linux).

Observe que testar se um determinado usuário é o proprietário é uma proposta diferente.

if [ -n "$(find . -user "$username" -print -prune -o -prune)" ]; then
  echo "The current directory is owned by $username."
fi
if [ -n "$(find . -user "$(id -u)" -print -prune -o -prune)" ]; then
  echo "The current directory is owned by the current user."
fi
Gilles 'SO- parar de ser mau'
fonte
ls | awkInfelizmente, existem algumas ressalvas na abordagem, como observei aqui . Ainda não encontrei uma solução para o problema "arquivo / diretório de destino é um link simbólico com um nome diferente", que mencionei em meu comentário recente.
Beporter
Em vez de find . -user "$username" -print -prune -o -prunevocê só poderia fazerfind . -maxdepth 0 -user "$username"
Niklas Holm
@ Gilles Existe alguma razão para você usar em awk 'NR==1 {print $3}'vez de apenas awk '{print $3}'? Não sei por que NR==1é necessário aqui.
Harold Fischer
1
@HaroldFischer Somente em um caso de borda em que o caminho contém uma nova linha. Raramente é necessário, mas nunca prejudicial.
Gilles 'SO- stop be evil'
@ Gilles Muito bom saber !! Apenas curioso, você está ciente de uma implementação de lsonde uma nova linha em um caminho faz com que a linha seja dividida em duas (que eu acredito que seja o caso extremo que você está tentando cobrir)? No GNU ls(versão nova), BusyBox lse FreeBSD, lsuma nova linha é retornada como $'\n', ?e ?, respectivamente.
Harold Fischer
9

Também é possível fazer isso com o GNU find:

find $directoryname -maxdepth 0 -printf '%u\n'

Isso não é portátil fora do sistema GNU, mas ficaria surpreso ao encontrar uma distribuição Linux onde não funcione.

mattdm
fonte
1
Isso funciona em todos os sistemas Linux não incorporados e em alguns outros (por exemplo, Cygwin). É provável que os sistemas embarcados possuam o Busybox , findque não possui -printf.
Gilles 'SO- stop be evil'
Como eu disse, sistema GNU.
mattdm
Sistemas sem coreutils GNU (como o FreeBSD) não possuem -printf:-(.
pevik 15/03/16
@ pevik Sim, como eu disse, ainda. Mas você pode instalar o GNU find se precisar. :)
mattdm
. @mattdm:. Nem sempre :-( mais importante quando você escrever scripts que deve ser portátil
pevik
2

No bash puro, você pode converter a saída de lsem uma matriz e indexá-la.

# (lrwxr-xr-x, 1, myuser, staff, 36, Oct, 21, 16:36, /path/to/file)    
file_meta=($(ls -ld /path/to/file))
file_owner="${file_meta[2]}" # myuser

Não é tão elegante como a utilização stat, findou awk, mas poderia trabalhar em uma pitada.

codehearts
fonte