Переменная окружения не раскрыта внутри аргумента командной строки

Переменная окружения не раскрыта внутри аргумента командной строки

У меня есть файл 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)

Изменения:

  1. командная строка awk использует двойные кавычки, поэтому $USR раскрывается
  2. знаки доллара и кавычки внутри программы awk экранируются
  3. $()используется вместо обратных кавычек, поэтомуобратные косые черты обрабатываются правильно

Обратите внимание, что поскольку значение USRинтерполируется непосредственно в скрипт awk, оно работает только в том случае, если это значение содержит только символы, которые awk будет интерпретировать буквально: если $USRоно содержит \или ", начнется настоящий ад — это  "будет конец строкового литерала awk, и \следующий символ будет взят в кавычки.

Связанный контент