Вопрос или проблема
Я пытаюсь запустить следующую команду, которая работает без проблем при запуске в терминале:
ogr2ogr -append -f PostgreSQL "PG:host=$PGHOST dbname=$PGDBNAME user=$PGUSER password=$PGPASS" \
--config OGR_TRUNCATE=YES "$FILENAME" -nln "${PGTABLEPREFIX}${PGTABLENAME}" \
-sql "SELECT * FROM elements WHERE OGR_GEOMETRY IN ('LINESTRING','MULTILINESTRING','LINE')" \
-s_srs EPSG:5514 -t_srs EPSG:4326 -nlt CONVERT_TO_LINEAR -nlt PROMOTE_TO_MULTI
Когда эта команда включена в состав bash-скрипта, возникает проблема с секцией SQL-запроса, которая интерпретируется неправильно следующим образом:
ogr2ogr -append -f PostgreSQL 'PG:host=xxx.xxx.xxx.xxx dbname=xxx user=gis password=xxxxxx' \
--config OGR_TRUNCATE=YES test.dgn -nln layer-test \
-sql 'SELECT * FROM elements WHERE OGR_GEOMETRY IN ('\''LINESTRING'\'','\''MULTILINESTRING'\'','\''LINE'\'')' \
-s_srs EPSG:5514 -t_srs EPSG:4326 -nlt CONVERT_TO_LINEAR -nlt PROMOTE_TO_MULTI
Я пробовал:
-sql $'SELECT * FROM elements WHERE OGR_GEOMETRY IN (\'LINESTRING\', \'MULTILINESTRING\', \'LINE\')'
- создать всю команду в переменной и выполнить её с помощью
eval
- больше комбинаций одинарных и двойных кавычек
Все с более или менее одинаковыми результатами. Как я могу сделать это правильно?
Ответ или решение
Проблема, с которой вы столкнулись, связана с неправильной интерпретацией одинарных кавычек в вашем SQL-запросе при запуске команды ogr2ogr
из Bash-скрипта. Когда вы используете одинарные кавычки, Bash интерпретирует содержимое буквально, и это может вызвать ошибки в SQL-запросе, так как внутри одинарных кавычек нельзя использовать другой символ одинарной кавычки. Давайте рассмотрим это более подробно и предложим решение.
Проблема с одинарными кавычками
Когда вы пишете ваш SQL-запрос следующим образом:
sql_query='SELECT * FROM elements WHERE OGR_GEOMETRY IN ('LINESTRING','MULTILINESTRING','LINE')'
Bash не сможет правильно понять вложенные одинарные кавычки. Это приводит к ошибкам при выполнении команды, так как в этом случае Bash ожидает закрытие кавычек.
Рекомендации по решению
Ваша цель — правильно экранировать одиночные кавычки или использовать различные конструкторы строк, чтобы избежать путаницы. Вот несколько подходов, которые могут помочь:
1. Использование двойных кавычек с экранированием
Вы можете использовать двойные кавычки для создания строки и экранировать одинарные кавычки внутри:
sql_query="SELECT * FROM elements WHERE OGR_GEOMETRY IN ('LINESTRING', 'MULTILINESTRING', 'LINE')"
Этот подход позволяет указывать строки внутри одинарных кавычек без необходимости экранирования.
2. Использование конструкции $'...'
для экранирования
В Bash также есть возможность использовать специальный синтаксис $'...'
, который позволяет использовать экранирование внутри строки:
sql_query=$'SELECT * FROM elements WHERE OGR_GEOMETRY IN (\'LINESTRING\', \'MULTILINESTRING\', \'LINE\')'
Этот вариант также будет работать и позволит разместить одинарные кавычки без конфликтов.
3. Построение команды в виде переменной
Вы можете собрать всю команду в одной переменной и выполнить ее с помощью eval
, однако это может быть менее безопасно и рекомендуется использовать с осторожностью:
command="ogr2ogr -append -f PostgreSQL \"PG:host=$PGHOST dbname=$PGDBNAME user=$PGUSER password=$PGPASS\" \
--config OGR_TRUNCATE=YES \"$FILENAME\" -nln \"${PGTABLEPREFIX}${PGTABLENAME}\" \
-sql \"$sql_query\" -s_srs EPSG:5514 -t_srs EPSG:4326 -nlt CONVERT_TO_LINEAR -nlt PROMOTE_TO_MULTI"
eval "$command"
4. Использование массива в Bash
Если ваш скрипт становится слишком сложным или длинным, использование массивов может значительно упростить составление команды:
command=(ogr2ogr -append -f PostgreSQL "PG:host=$PGHOST dbname=$PGDBNAME user=$PGUSER password=$PGPASS" \
--config OGR_TRUNCATE=YES "$FILENAME" -nln "${PGTABLEPREFIX}${PGTABLENAME}" \
-sql "SELECT * FROM elements WHERE OGR_GEOMETRY IN ('LINESTRING', 'MULTILINESTRING', 'LINE')" \
-s_srs EPSG:5514 -t_srs EPSG:4326 -nlt CONVERT_TO_LINEAR -nlt PROMOTE_TO_MULTI)
"${command[@]}"
Этот метод позволяет избежать потенциальных конфликтов со специальными символами и улучшает читаемость скрипта.
Заключение
Ваша проблема с одинарными кавычками в SQL-запросе в Bash-скрипте может быть решена с помощью правильного подхода к экранированию и построению строк. Рекомендуем использовать двойные кавычки или конструкцию с $'...'
, а также рассмотреть возможность построения команды в виде массива для лучшей читаемости и удобства. Применяя эти методы, вы сможете избежать распространенных ошибок и упростить процесс работы вашего скрипта.