Eu tenho tentado encontrar a resposta para esta pergunta há algum tempo. Estou escrevendo um script rápido para executar um comando com base na saída do 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
Os problemas são que o -c
argumento usa um comando entre aspas simples e não consigo descobrir como escapar disso adequadamente e que $1
não se expande para o nome de usuário.
Basicamente, estou apenas tentando obtê-lo:
xfs_quota -x -c 'limit bsoft=5g bhard=6g userone' /home
xfs_quota -x -c 'limit bsoft=5g bhard=6g usertwo' /home
etc ...
awk
Respostas:
Para executar o comando
xfs_quota -x -c 'limit bsoft=5g bhard=6g USER' /home
para cada umUSER
cujo UID seja pelo menos$ID_minimum
, considere analisar primeiro esses usuários e, em seguida, execute o comando, em vez de tentar criar uma sequência que represente o comando que você deseja executar.Se você criar a cadeia de comando, você precisaria
eval
. É complicado e fácil de errar. É melhor apenas obter uma lista de nomes de usuários e depois executar o comando.Observe que não há necessidade real de aspas simples ao redor do argumento a seguir
-c
. Aqui eu uso aspas duplas porque quero que o shell expanda a$user
variável que contém valores extraídos porawk
.Eu uso
${ID_minimum:-1000}
ao dar o valor para amin
variável noawk
comando. Isso será expandido para o valor de$ID_minimum
ou1000
se essa variável estiver vazia ou não definida.Se você realmente quisesse, poderia fazer o loop acima imprimir os comandos em vez de executá-los:
Observe novamente que o uso de aspas duplas na cadeia de comando gerada (em vez de aspas simples) não confundiria um shell de forma alguma se você executasse os comandos gerados usando
eval
ou através de outros meios. Se isso lhe incomoda, basta trocar as aspas simples e duplas no primeiro argumento paraprintf
cima.fonte
getent
(na área de trabalho, de qualquer maneira), e a pergunta não está marcada como "linux"./home
não é realmente usado no macOS (está lá, mas geralmente está vazio).Isso é um pouco bobo, já que não há realmente nenhum loop com apenas um valor.
Mas o problema parece estar imprimindo aspas simples do awk. Você pode escapar deles no shell, mas também pode usar escapes de barra invertida no awk para imprimi-los. é o caractere com valor numérico OOO (em octal ), assim é . Portanto, essa seria uma maneira de fazer isso:
\OOO
\047
'
Você pode usar o escape semelhante em hexadecimal,
\x27
mas ele pode ser mal interpretado em algumas implementações se o caractere a seguir for um dígito hexadecimal válido. (E é claro que eu assumi ASCII ou um conjunto de caracteres compatível com ASCII, por exemplo, UTF-8.)fonte
l
não é um dígito hexadecimal, mas"\x27df\n"
seria tratado como"\x27" "df"
no busybox awk ou mawk, mas como"\xdf"
(0x27df
convertido para char de 8 bits) no original awk e gawk (essa é a razão pela qual o POSIX não especifica\xHH
). Octals (\047
) não têm o mesmo problema e são POSIX. Em qualquer caso, isso pressupõe um sistema ASCII (uma suposição razoável nos dias de hoje).Use a
-f -
opção awk para obter o script stdin e um documento here:fonte
Isso foi feito.
fonte
'\''
ou'"'"'
. Ambos funcionam, ambos parecem irritantes.É um alojamento horrível, mas é rápido e fácil ...
fonte
Isso me parece uma oportunidade ideal para empregar alguns
xargs
(ou GNU Parallel ):A vantagem de usar
xargs
ouparallel
é que você pode simplesmente remover oecho
quando estiver pronto para executar o comando de verdade (possivelmente substituindo-o porsudo
, se necessário).Você também pode usar as opções desses utilitários
-p
/--interactive
(o último é somente GNU) ou--dry-run
(parallel
apenas), para obter confirmação antes de executar cada um ou apenas para ver o que seria executado antes de executá-lo.O método geral usado acima deve funcionar na maioria dos Unixes e não requer
xargs
opções específicas do GNU . As aspas duplas fazer necessidade de ser "escapado" para que eles aparecem literalmente na saída. Note que a "cadeia de substituição,"{}
, noxargs -I{}
pode ser qualquer coisa que você prefere, e-I
implica-L1
(executar um comando por linha de entrada ao invés de lotes-los).GNU Parallel não requer a
-I
opção ({}
é a cadeia de substituição padrão), e dá-lhe a gratificação instantânea de correr muitos postos de trabalho em paralelo, mesmo se você não quer incomodar a aprender sobre qualquer de suas outras características .Como uma observação lateral, nem tenho certeza se
xfs_quota
a-c
opção deve ser usada assim, embora eu não tenha sistemas de arquivos XFS à mão para testar. Você pode nem ter precisado lidar com uma string citada em primeiro lugar (a menos que espere nomes de usuários com espaços em branco, o que eu acho que é possível), pois parece que você pode dar várias-c
opções na mesma linha de comando, de acordo com para a página de manual incluída emxfsprogs
4.5.algo.fonte
Com o GNU Parallel, você pode:
Explicação:
--colsep :
Dividir em:-q
não divida o comando em espaços (mantenha o '...' como uma única sequência){=1 ... =}
Avalie esta expressão perl no primeiro argumento da linha$_ eq "nfsnobody" and skip();
Se o valor == nfsnobody: skip$arg[3] <= 1000 and skip();
Se argument3 <= 1000: skipfonte