У меня есть файл user-pid.out2
, в котором есть «usernumber» и «process id» в виде двух столбцов. На основе usernumber я хочу найти соответствующий идентификатор процесса. Первые две строки ниже не показывают правильный вывод, но когда я жестко кодирую пользователя как 62 в строках 3 и 4, отображается идентификатор процесса, соответствующий пользователю 62. Может ли кто-нибудь помочь, пожалуйста.
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
решение1
@artm показал технику, в которой вы заключаете скрипт awk в двойные кавычки и экранируете различные символы. Вот еще 3 техники
Выйти из одинарной кавычки, чтобы позволить оболочке расширить переменную
usrpid=$(awk '$1 == "'"$USR"'" {print $2}' file)
Передать переменную оболочки в переменную awk
usrpid=$(awk -v usr="$USR" '$1 == usr {print $2}' file)
Если переменная экспортируется, используйте массив ENVIRON awk
usrpid=$(awk '$1 == ENVIRON["USR"] {print $2}' file)
Последний вариант следует считать предпочтительным.
В первом подходе, подобном подходу @artm, содержимое переменной оболочки внедряется в awk
код, так что это становитсяуязвимость инъекции командесли содержимое переменной не контролируется жестко (например, с помощью USR='blah" || system("reboot") || "'
, это приведет к вызову reboot
).
Во втором случае не возникает уязвимости внедрения команд, но если переменная $USR
содержит символы обратной косой черты, она usr
awk
не будет содержать то же самое, что и $USR
переменная оболочки, поскольку awk
в ней развернуты управляющие последовательности обратной косой черты в стиле C.
При использовании ENVIRON
таких проблем нет.
решение2
в "$USR"
первом примере не раскрывается, поскольку находится внутри строки в одинарных кавычках '$1 == "$USR" { print $2 }'
, поэтому этот код ищет строку, в которой первый столбец равен «$USR», а не 62.
Должно сработать следующее:
usrpid=$(awk "\$1 == \"$USR\" {print \$2}" /home/hu/batchhu/dbscripts_tst2/user-pid.out2)
Изменения:
- командная строка awk использует двойные кавычки, поэтому $USR раскрывается
- знаки доллара и кавычки внутри программы awk экранируются
$()
используется вместо обратных кавычек, поэтомуобратные косые черты обрабатываются правильно
Обратите внимание, что поскольку значение USR
интерполируется непосредственно в скрипт awk, оно работает только в том случае, если это значение содержит только символы, которые awk будет интерпретировать буквально: если $USR
оно содержит \
или "
, начнется настоящий ад — это "
будет конец строкового литерала awk, и \
следующий символ будет взят в кавычки.