Я пытаюсь создать список пользователей, чей домашний каталог не существует. Кажется, я должен быть в состоянии сделать это с помощью awk, но что-то не так с моим синтаксисом.
Он продолжает говорить мне «Неверный синтаксис» в]. Что я делаю неправильно?
awk -F: '{ if(![ -d "$6"]){ print $1 " " $3 " " $7}}' /etc/passwd
Последний код, который я, вероятно, собираюсь использовать:
awk -F: '{if(system( "[ -d " $6 " ]") == 1 && $7 != "/sbin/nologin" ) {print "The directory " $6 " does not exist for user " $1 }}' /etc/passwd
И у меня есть связанный вопрос здесь .
/bin/ls
:echo ';ls;' | awk '{ print system("[ ! -d " $1 " ]") }'
Я не думаю, что
[ -d ]
этоawk
вещь, это вещь оболочки. Я бы просто сделал это так:Конечно, как очень правильно указал @Janis, вы можете сделать все это в оболочке:
источник
awk
самом деле это не нужно; так как вы в любом случае зацикливаетесь в оболочке, вы также можете сделать этоwhile 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"]
на самом деле это синтаксис bash, а не awk. В[
выглядит как нормальный синтаксис, но (в одном из Баша / лучше weirdnesses для Linux) это фактически синонимtest
исполняемой программы (или , возможно , Баш встроенного версии этого, и, просто чтобы быть страннее, Баш требует согласований ,]
что Безразлично не делай ничего, о чем я знаю, кроме как вводить тебя в заблуждение и думать, что все дело в синтаксисе, а не в программе). В любом случае, это не то, о чем знает awk. Вот почему вам нужнаsystem()
функция для доступа к ней, ссылаясь на нее в контексте bash, где она понимаетсяВы можете использовать getline :
источник
awk
, но, к сожалению, не работает для каталогов.Если вы действительно используете
gawk
(хотя вы можете использоватьnawk
, илиmawk
, в этом случае это не будет применяться), вы можете сделать это изначально, используя одно из загружаемых расширений, доступных начиная с версии 4.0. Я используюgawk-4.1.x
(v4.0 имел вариацию синтаксиса для загрузки расширений).Загрузка
filefuncs
расширения добавляет (среди прочего)stat()
функцию:См.
filefuncs(3am)
Справочную страницу для деталей об этом расширении.Запустите что-то вроде:
Вы можете подтвердить, что ваш
gawk
двоичный файл поддерживает расширения:Помимо:
gawk
также поставляется с небольшой библиотечной функцией для чтенияpasswd
файла, вы можете вызвать его следующим образом:Я предпочитаю использовать
getent
в системах Linux / glibc, так как он поддерживает nsswitch.источник
gawk
v4 предлагает это. Спасибо!Это почти ужасно ...
источник
Вот решение, которое
gawk
и/bin/sh
Код:
пояснил:
IFS="" read -r dir; [ -d "$dir" ]; echo $?
это шелл-код, который читает путь из стандартного ввода и выводит,0
если это каталог, иначе1
print $6 |& cmd
передает имя файла в команду.|&
является расширением GNU-awk.cmd |& getline x
читает вывод команды в GNU-awkclose(cmd)
завершает команду, поэтому следующая строка может выполнить ее еще разif (x)
выполняетprint
только еслиx
нет0
(поэтому каталог не существует)Я не рекомендую делать это таким образом, потому что это очень медленно и неуклюже. Но этот рецепт безопасен , так что неправильный ввод не может причинить вред. (Маловероятно, что он
/etc/passwd
содержит вредоносные данные, но, возможно, кто-то захочет использовать его с данными из ненадежного источника).Если вы не можете использовать
gawk
, это прискорбно. В этом случае у вас нет|&
.awk
Только обычный может выполнить одно из следующих трех:print "data" | cmd; close(cmd)
: Передать данные в командуgetline data < cmd; close(cmd)
: Чтение данных из командыret = system(cmd)
: Получить код возврата команды«Обычный»
awk
просто не может передать данные в скрипт и получить что-то из него одновременно (по крайней мере, я не нашел пути для этого), поэтому вам нужен какой-то промежуточный файл (временный файл), который еще более неуклюжий.Интересно отметить, что такую простую задачу можно выполнить и с помощью одной оболочки:
Вам не нужно
bash
, каждая нормальная оболочка Bourne может выполнить приведенный выше код.Обратите внимание, что приведенный выше код оболочки немного сложнее, чем действительно необходимо, но это должен быть указатель на то, как на самом деле работать с ним (для людей, не совсем разбирающихся в том, как работает оболочка).
источник