Estou tentando gerar uma lista de usuários que possuem um conjunto de diretórios pessoais que não existe. Parece que eu deveria conseguir fazer isso com o awk, mas algo está errado com a minha sintaxe.
Ele continua dizendo "Sintaxe inválida" no]. O que estou fazendo errado?
awk -F: '{ if(![ -d "$6"]){ print $1 " " $3 " " $7}}' /etc/passwd
O código final que provavelmente vou usar é:
awk -F: '{if(system( "[ -d " $6 " ]") == 1 && $7 != "/sbin/nologin" ) {print "The directory " $6 " does not exist for user " $1 }}' /etc/passwd
E eu tenho uma pergunta relacionada aqui .
/bin/ls
:echo ';ls;' | awk '{ print system("[ ! -d " $1 " ]") }'
Eu não acho que isso
[ -d ]
é umaawk
coisa, é uma coisa de casca. Eu apenas faria desta maneira:Obviamente, como bem apontado por @Janis, você pode fazer tudo no shell:
fonte
awk
não é realmente necessário; desde que você faça um loop no shell de qualquer maneira, você também pode fazerwhile IFS=: read -r name x uid x x x shell rest ; do ... ; done </etc/passwd
.awk -F: '{print $6}' /etc/passwd | while read dir; do [ -d "$dir" ] || echo "no results for $dir"; done
.[ -d "$6"]
na verdade é a sintaxe do bash, não o awk. Os[
olhares como a sintaxe normal do, mas (em um dos festança / melhores estranhezas do Linux) é realmente um sinônimo para otest
programa executável (ou talvez uma festa de built-in versão dele, e, apenas para ser mais estranho, o bash exige uma correspondência]
que doesn faça qualquer coisa que eu saiba além de induzi-lo a pensar que a coisa toda é realmente sintaxe e não um programa). De qualquer forma, não é algo que a awk saiba. É por isso que você precisa dasystem()
função para acessá-lo por referência a ele no contexto de festa, onde se entendeVocê pode usar o getline :
fonte
awk
, mas infelizmente não funciona para diretórios.Se você realmente estiver usando
gawk
(embora possa estar usandonawk
, oumawk
, nesse caso, isso não se aplicará), você pode fazer isso nativamente usando uma das extensões carregáveis disponíveis desde a v4.0. Estou usandogawk-4.1.x
(v4.0 tinha uma variação na sintaxe para carregar extensões).O carregamento da
filefuncs
extensão adiciona (entre outras) umastat()
função:Consulte a
filefuncs(3am)
página do manual para obter detalhes sobre esta extensão.Execute com algo como:
Você pode confirmar que seu
gawk
binário suporta extensões com:Além:
gawk
também vem com uma pequena função de biblioteca para ler opasswd
arquivo, você pode invocá-lo como:Eu prefiro usar
getent
em sistemas Linux / glibc, pois suporta nsswitch.fonte
gawk
ofertas v4 isso. Obrigado!É quase estranho ...
fonte
Aqui está uma solução que
gawk
e/bin/sh
Código:
explicado:
IFS="" read -r dir; [ -d "$dir" ]; echo $?
é um código de shell que lê um caminho do stdin e gera0
um diretório, caso contrário1
print $6 |& cmd
canaliza o nome do arquivo para o comando|&
é uma extensão GNU-awk.cmd |& getline x
lê a saída do comando no GNU-awkclose(cmd)
finaliza o comando, para que a próxima linha possa executar uma novamenteif (x)
executa oprint
único sex
não estiver0
(portanto, o diretório não existe)Porém, eu não recomendo fazê-lo dessa maneira, porque é muito lento e desajeitado. Mas esta receita é segura , de modo que entradas irregulares não podem causar danos. (É improvável que
/etc/passwd
contenha dados prejudiciais, mas talvez alguém queira usá-los com dados de uma fonte não confiável).Se você não pode usar
gawk
, isso é lamentável. Nesse caso, você não tem|&
. Normalawk
apenas pode executar um dos três seguintes:print "data" | cmd; close(cmd)
: Canalize dados em um comandogetline data < cmd; close(cmd)
: Ler dados de um comandoret = system(cmd)
: Obtenha o código de retorno do comando"Normal"
awk
simplesmente não pode canalizar dados para um script e obter algo novamente, ao mesmo tempo (pelo menos não encontrei uma maneira de fazê-lo), então você precisa de algum arquivo intermediário (tempfile) que é ainda mais desajeitado.A observação interessante é que uma tarefa tão fácil também pode ser realizada apenas com o shell:
Você não precisa
bash
, cada Bourne-shell normal pode executar o código acima.Observe que o código do shell acima é um pouco mais elaborado do que o realmente necessário, mas isso deve ser um indicativo de como realmente trabalhar com ele (para pessoas que não têm muita experiência em como o shell funciona).
fonte