Анализировать строки в hive с помощью shell

У меня есть сценарий оболочки, который я использую для синтаксического анализа строковой переменной в Hive, чтобы отфильтровать свои наблюдения. Я предоставляю как скрипт, так и код улья ниже.

В следующем скрипте у меня есть переменная со строковым значением, и я пытаюсь проанализировать ее в улье, как показано ниже:

Сценарий оболочки:

name1='"Maria Nash"' *(I use a single quote first and then a double)*

hive --hiveconf name=${name1} -f t2.hql

Код улья (t2.hql)

create table db.mytable as

SELECT *

FROM db.employees

WHERE emp_name='${hivevar:name}';

Заключение

Если быть точным, итоговая таблица создана, но не содержит никаких наблюдений. В таблице сотрудников есть наблюдения, у которых есть emp_name "Maria Nash".

Я думаю, что могу неправильно проанализировать строку из оболочки или не соблюдаю правильный синтаксис того, как я должен обрабатывать проанализированную переменную в запросе улья.

Буду признателен за вашу помощь!

Почему вы используете одинарные + двойные кавычки. Достаточно двойных кавычек. они будут удалены при передаче в Hive, а в Hive вы добавили одинарные кавычки, это правильно. Или ваше emp_name содержит двойные кавычки?

leftjoin 31.10.2018 12:21

@leftjoin Пожалуйста, проверьте еще раз мой пример. Я изменил это. Я заменил «Мария» на строку типа «Мария Наш». Это могло быть иначе.

Vamkos 31.10.2018 12:31

кавычки обрабатываются оболочкой, но когда вы используете кавычки внутри цитируемого выражения, они являются частью строкового значения, вы можете использовать, например, name1='Maria Nash', затем hive --hiveconf name="${name1}" -f t2.hql, двойные кавычки важны при расширении параметров, проблема заключается в использовании name=${name1} без кавычек

Nahuel Fouilleul 31.10.2018 12:45

@NahuelFouilleul Это правильный ответ. Спасибо!

Vamkos 31.10.2018 12:52

Добавьте это как первую строку в скрипт Hive: `! echo emp_name = '$ {hivevar: name}' `- пробел +! это команда оболочки, выполняемая из Hive. Это напечатает ваш параметр

leftjoin 31.10.2018 12:54
0
5
748
2

Ответы 2

Использование интерфейса командной строки - устарел

вы можете использовать beeline из сценария оболочки

это должно выглядеть примерно так

beeline << EOF

!connect jdbc:hive2://host:port/db username password

select * 
from db.employees
where emp_name = "${1}"

EOF

предполагая, что $ 1 - это вход из сценария.

Это пример того, как это сделать, а не производственная реализация. В целом,

  1. Kerberos будет включен, поэтому имя пользователя и пароль не будут там и действующий токен будет доступен
  2. Проверьте входные параметры.

Учитывая, что вы можете сделать это в одной строке

beeline -u jdbc:hive2://hostname:10000  -f {full Path to Script} --hivevar {variable}={value}

Это ожидаемая атака с использованием SQL-инъекции. Вы не передаете значение запросу; вы динамически строительство запрос из переменной, которая может содержать произвольный фрагмент SQL.

chepner 31.10.2018 14:57

изменил его, но все же это обычно зависит от того, как вы передаете параметры в скрипт

shaine 01.11.2018 14:55

Проблема в where emp_name = "${1}". Предположим, что $1 - это 1; drop table db.employees. Запрос, который видит beeline, теперь select * from db.employees where emp_name = 1; drop table db.employees, а не select * from db.employees where emp_name = '1; drop table db.employees'.

chepner 01.11.2018 15:06

но это верно для любого параметризованного скрипта без какой-либо проверки полей, я понимаю, что вы имеете в виду, но это кажется немного тупым. вы могли бы улучшить мой ответ, добавив проверку поля.

shaine 02.11.2018 13:03

Идея в том, что вы не строите запрос в bash. Я не знаю, каковы возможности beeline, но представьте, что вы могли бы назвать его так: beeline 'select * from db.employees where emp_name = %s' "$1". Теперь ты не строит запрос; вы говорите beeline взять значение $1 и вставить его в запрос, где находится %s, но безопасно, чтобы вы не смешивали код и данные.

chepner 02.11.2018 13:39

вы передаете переменную в пространстве имен hiveconf, но в сценарии sql используется hivevar, вы также должны использовать hiveconf:

WHERE emp_name=${hiveconf:name} --hiveconf, not hivevar

Другие вопросы по теме