Я пытался найти ответ на этот вопрос некоторое время. Я пишу быстрый скрипт для запуска команды, основанной на выводе из awk.
ID_minimum=1000
for f in /etc/passwd;
do
awk -F: -vID=$ID_minimum '$3>=1000 && $1!="nfsnobody" { print "xfs_quota -x -c 'limit bsoft=5g bhard=6g $1' /home "}' $f;
done
Проблема в том, что -c
аргумент принимает команду в одинарных кавычках, и я не могу понять, как правильно избежать этого, а также того, что $1
не распространяется на имя пользователя.
По сути, я просто пытаюсь получить его на выходе:
xfs_quota -x -c 'limit bsoft=5g bhard=6g userone' /home
xfs_quota -x -c 'limit bsoft=5g bhard=6g usertwo' /home
так далее...
awk
Ответы:
Чтобы запустить команду
xfs_quota -x -c 'limit bsoft=5g bhard=6g USER' /home
для каждого пользователя,USER
чей UID хотя бы$ID_minimum
минимален, рассмотрите сначала анализ этих пользователей, а затем фактически запустите команду, а не пытайтесь создать строку, представляющую команду, которую вы хотите запустить.Если вы создадите командную строку, вам придется к
eval
ней. Это легко и легко ошибиться. Лучше просто получить список имен пользователей и затем запустить команду.Обратите внимание, что нет реальной необходимости в одинарных кавычках вокруг аргумента после
-c
. Здесь я использую двойные кавычки, потому что я хочу, чтобы оболочка раскрыла$user
переменную, которая содержит значения, извлеченные с помощьюawk
.Я использую
${ID_minimum:-1000}
при присвоении значенияmin
переменной вawk
команде. Это расширится до значения$ID_minimum
или,1000
если эта переменная пуста или не установлена.Если вы действительно хотите, вы можете заставить вышеприведенный цикл выводить команды вместо их выполнения:
Еще раз обратите внимание, что использование двойных кавычек в выводимой командной строке (вместо одинарных кавычек) никоим образом не будет путать оболочку, если вы будете выполнять сгенерированные команды с использованием
eval
или каким-либо другим способом. Если это вас беспокоит, просто поменяйте местами одинарные и двойные кавычки в первом аргументеprintf
выше.источник
getent
(на рабочем столе, во всяком случае), и вопрос не помечен как «linux»./home
самом деле не используется в macOS (он есть, но обычно пустой).Это немного глупо, поскольку в действительности нет цикла с одним значением.
Но проблема, кажется, печатает одинарные кавычки из awk. Вы можете избежать их в оболочке, но вы также можете использовать обратную косую черту в awk для их печати. символ с числовым значением ООО (в восьмеричном выражении ), то есть . Так что это будет один из способов сделать это:
\OOO
\047
'
Вы можете использовать аналогичный escape в шестнадцатеричном
\x27
формате, но в некоторых реализациях он может быть неверно истолкован, если следующий символ является действительной шестнадцатеричной цифрой. (И, конечно, я предполагал ASCII или ASCII-совместимый набор символов, например UTF-8.)источник
l
это не шестнадцатеричная цифра, а"\x27df\n"
будет рассматриваться как"\x27" "df"
в awbox или mawk busybox, а как"\xdf"
(0x27df
приведение к 8-битному символу) в оригинальном awk и gawk (именно поэтому POSIX не указывает\xHH
). Octals (\047
) не та же проблема и POSIX. В любом случае это предполагает систему ASCII (разумное предположение в наши дни).Используйте
-f -
опцию awk, чтобы взять скрипт из stdin и документ здесь:источник
Это сделал это.
источник
'\''
или'"'"'
. Оба работают, оба выглядят надоедливыми.Это ужасная уловка, но это быстро и легко ...
источник
Это выглядит как идеальная возможность нанять вас
xargs
(или GNU Parallel ):Преимущество использования
xargs
илиparallel
заключается в том, что вы можете просто удалить,echo
когда будете готовы запустить команду по-настоящему (возможно, заменив ееsudo
, если необходимо).Вы также можете использовать опции
-p
/--interactive
(последние только для GNU) или--dry-run
(parallel
только) этих утилит , чтобы получить подтверждение перед запуском каждого или просто посмотреть, что будет запущено, прежде чем запускать его.Общий метод, использованный выше, должен работать в большинстве Unix-систем и не требует специфических для GNU
xargs
опций. Двойные кавычки делают необходимость быть «убежали» , так что они появляются буквально на выходе. Обратите внимание , что «строка замены»{}
, вxargs -I{}
может быть все , что угодно, и-I
предполагает-L1
(запустить одну команду за входной линии , а не дозированием их).GNU Parallel не требует
-I
опции ({}
это замена строки по умолчанию), и дает вам мгновенный бонус работает много рабочих мест , параллельно, даже если вы не хотите заморачиваться узнать о какой - либо из его других особенностей .В качестве примечания, я даже не уверен , что
xfs_quota
«S-c
опция должна быть использована , как это, хотя у меня нет XFS не файловые системы удобно проверить. Вам, возможно, даже не понадобилось иметь дело с строкой в кавычках (если вы не ожидаете, что имена пользователей с пробелами в них, что я думаю, возможно), так как похоже, что вы можете задать несколько-c
параметров в одной командной строке, в зависимости от на страницуxfsprogs
руководства, включенную с 4.5.источник
С GNU Parallel вы можете делать:
Объяснение:
--colsep :
Разделить на:-q
не разбивать команду на пробелы (сохраняйте '...' как одну строку).{=1 ... =}
Оцените это выражение perl по первому аргументу строки.$_ eq "nfsnobody" and skip();
Если значение == nfsnobody: пропустить,$arg[3] <= 1000 and skip();
если аргумент3 <= 1000: пропустить.источник