Eu tenho um arquivo user-pid.out2
que possui "usernumber" e "process id" como duas colunas. com base no número do usuário, quero encontrar o ID do processo correspondente. as duas primeiras linhas abaixo não mostram a saída correta, mas quando codifico o usuário como 62 nas linhas 3 e 4, ele mostra o ID do processo correspondente ao usuário 62. Alguém poderia ajudar, por favor.
USR=62
usrpid=`awk '$1 == "$USR" {print $2}' /home/hu/batchhu/dbscripts_tst2/user-pid.out2`
echo "first:" $USR $usrpid
# This shows 62 and blank for process id
usrpid=`awk '$1 == "62" {print $2}' /home/hu/batchhu/dbscripts_tst2/user-pid.out2`
echo "second:" $USR $usrpid
# This shows 62 and process id corresponding to this user in the file user-pid.out2
Responder1
@artm mostrou uma técnica em que você coloca aspas duplas no script awk e escapa de vários caracteres. Aqui estão três outras técnicas
Saia das aspas simples para permitir que o shell expanda a variável
usrpid=$(awk '$1 == "'"$USR"'" {print $2}' file)
Passe a variável shell para uma variável awk
usrpid=$(awk -v usr="$USR" '$1 == usr {print $2}' file)
Se a variável for exportada, use o array ENVIRON do awk
usrpid=$(awk '$1 == ENVIRON["USR"] {print $2}' file)
Este último deve ser o preferido.
Na primeira abordagem, como na de @artm, o conteúdo da variável shell é incorporado dentro do awk
código, de modo que se torna umvulnerabilidade de injeção de comandose o conteúdo da variável não for rigidamente controlado (por exemplo, with USR='blah" || system("reboot") || "'
, isso chamaria reboot
).
O segundo não introduz uma vulnerabilidade de injeção de comando, mas se $USR
contiver caracteres de barra invertida, a usr
awk
variável não conterá a mesma coisa que a $USR
variável shell, pois awk
expande sequências de escape de barra invertida semelhantes a C.
Usar ENVIRON
não tem nenhum desses problemas.
Responder2
o "$USR"
no primeiro exemplo não é expandido porque ocorre dentro da string entre aspas simples '$1 == "$USR" { print $2 }'
, então este código está procurando uma linha com a primeira coluna sendo "$USR", não 62.
O seguinte deve funcionar:
usrpid=$(awk "\$1 == \"$USR\" {print \$2}" /home/hu/batchhu/dbscripts_tst2/user-pid.out2)
Mudanças:
- a linha de comando do awk usa aspas duplas, então $USR é expandido
- cifrões e caracteres de aspas dentro do programa awk são escapados
$()
é usado em vez de crases, entãoas barras invertidas são tratadas corretamente
Observe que, como o valor de USR
é interpolado diretamente no script awk, ele só funciona se esse valor contiver apenas caracteres que o awk interpretará literalmente: se $USR
contém \
ou "
, o inferno vai explodir - "
seria o fim da string awk literal, e \
citaria o próximo caractere.