Estoy tratando de generar una lista de usuarios que tienen un conjunto de directorios de inicio que no existe. Parece que debería poder hacer esto con awk, pero algo está mal con mi sintaxis.
Sigue diciéndome "Sintaxis inválida" en el]. ¿Qué estoy haciendo mal?
awk -F: '{ if(![ -d "$6"]){ print $1 " " $3 " " $7}}' /etc/passwd
El código final que probablemente terminaré usando es:
awk -F: '{if(system( "[ -d " $6 " ]") == 1 && $7 != "/sbin/nologin" ) {print "The directory " $6 " does not exist for user " $1 }}' /etc/passwd
Y tengo una pregunta relacionada aquí .
/bin/ls
:echo ';ls;' | awk '{ print system("[ ! -d " $1 " ]") }'
No creo que
[ -d ]
sea unaawk
cosa, eso es una cáscara. En cambio, lo haría de esta manera:Por supuesto, como señaló muy correctamente @Janis, puede hacer todo en el shell:
fuente
awk
no se necesita realmente; ya que de todos modos puedes hacer un bucle en shell, también puedes hacerlowhile 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"]
realidad es una sintaxis bash, no awk. Las[
miradas como la sintaxis normal, pero (en uno de bash / mejores weirdnesses de Linux) en realidad es un sinónimo para eltest
programa ejecutable (o tal vez una fiesta de versión integrada de la misma, y, sólo para estar más raro, fiesta requiere una coincidencia]
que doesn no haga nada de lo que tenga conocimiento que no sea engañarlo para que piense que todo es realmente sintaxis y no un programa). En cualquier caso, no es algo que awk sepa. Es por eso que necesita lasystem()
función para acceder a ella al hacer referencia a ella en el contexto de bash donde se entiendePuedes usar getline :
fuente
awk
, pero desafortunadamente no funciona para directorios.Si realmente está utilizando
gawk
(aunque puede estar utilizandonawk
, omawk
, en cuyo caso esto no se aplica), puede hacerlo de forma nativa utilizando una de las extensiones cargables disponibles desde v4.0. Estoy usandogawk-4.1.x
(v4.0 tenía una variación en la sintaxis para cargar extensiones).Al cargar la
filefuncs
extensión se agrega (entre otras) unastat()
función:Consulte la
filefuncs(3am)
página del manual para obtener detalles sobre esta extensión.Corre con algo como:
Puede confirmar que su
gawk
binario admite extensiones con:Aparte:
gawk
también viene con una pequeña función de biblioteca para leer elpasswd
archivo, puede invocarlo como:Prefiero usar
getent
en sistemas Linux / glibc ya que admite nsswitch.fuente
gawk
v4 ofrece esto. ¡Gracias!Es casi awk ...
fuente
Aquí hay una solución que
gawk
y/bin/sh
Código:
explicado:
IFS="" read -r dir; [ -d "$dir" ]; echo $?
es un código de shell que lee una ruta desde stdin y genera salidas0
si es un directorio, de lo contrario1
print $6 |& cmd
canaliza el nombre del archivo al comando.|&
es una extensión GNU-awk.cmd |& getline x
lee la salida del comando en GNU-awkclose(cmd)
finaliza el comando, por lo que la siguiente línea puede ejecutar uno nuevamenteif (x)
ejecuta elprint
único ifx
is not0
(por lo que el directorio no existe)Sin embargo, no recomiendo hacerlo de esta manera, porque es muy lento y torpe. Pero esta receta es segura , de modo que la entrada irregular no puede hacer daño. (Es poco probable que
/etc/passwd
contenga datos dañinos, pero tal vez alguien quiera usarlo con datos de una fuente no confiable).Si no puede usar
gawk
, esto es lamentable. En ese caso no tienes|&
. Normalawk
solo puede hacer uno de los siguientes tres:print "data" | cmd; close(cmd)
: Canalizar datos en un comandogetline data < cmd; close(cmd)
: Leer datos de un comandoret = system(cmd)
: Obtener el código de retorno del comando"Normal"
awk
simplemente no puede canalizar datos en un script y obtener algo de él nuevamente al mismo tiempo (al menos no encontré una manera de hacerlo), por lo que necesita un archivo intermedio (archivo temporal) que sea aún más torpe.La observación interesante es que una tarea tan fácil se puede hacer solo con el shell:
No es necesario
bash
, cada Bourne-shell normal puede ejecutar el código anterior.Tenga en cuenta que el código de shell anterior es un poco más elaborado de lo que realmente se necesita, pero esto será un indicador de cómo trabajar realmente con él (para personas que no tienen experiencia completa en cómo funciona shell).
fuente