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

У меня есть файл user-pid.out2 который имеет «usernumber» и «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 

@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 содержит символы обратной косой черты, переменная awk usr не будет содержать ту же самую вещь, что и переменная оболочки USRUS, поскольку awk расширяет C-подобные escape-последовательности обратной косой черты.

Использование ENVIRON имеет этих проблем.

"$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 и \ цитирует следующий символ.