Using subprocess.call from python that contains escaped characters - oracle

am triggering SQL loader from a python script (2.7);
The password does contain an # sign. If I call sql loader from the command line and escape the password (username/\"p#ssword\"#database) the process works. However, when I apply what I believe is the same logic within a python script I get an error:
SQL*Loader-704: Internal error: ulconnect: OCIServerAttach [0]
ORA-12154: TNS:could not resolve the connect identifier specified
Since I can run the same command in the cmd prompt successfully, I don't believe this is an issue with the TNSNAMES.ORA file containing any incorrect or missing parameters. I'm pretty confident this is an issue with calling SQL loader from the subprocess command and the escape characters.
Python Logic:
subprocess.call("sqlldr userid=" +config.ddw["user"] + "/\"" +
config.ddw["password"] +"\"#" + config.ddw["connection"] + "
control=C:/projects/controlFile.ctl log=C:/logFile.log)
If I print this statement the string looks like:
sqlldr userid=USERNAME/"p#ssw0rd"#connection/db
(2.7)control=C:/projects/controlFile.ctl log=C:/logFile.log
When I load the string directly in the command line it works:
sqlldr userid=USERNAME/\"p#ssw0rd\"#connection/db
control=C:/projects/controlFile.ctl log=C:/logFile.log

You need those double-quotes escaped so sqlldr sees them. I don't know python, but it appears you need to change that code to make sure you get a backslash in front of the double-quotes. You may need to escape the backslash too since it is most likely a special character.
Perhaps something like this?
subprocess.call("sqlldr userid=" +config.ddw["user"] + "/\\"" +
config.ddw["password"] +"\\"#" + config.ddw["connection"] + "
This is a SWAG so your mileage may vary a little :-)

Related

Concatenation in groovy + bash

I ran into a small problem when trying to create a shell line in groovy that is stapled from many variables.
Here is what it looks like:
sh("""
java -jar Report.jar settings.xml "$startTest" "$durationTest" "$opt" empty iReport:gReport:aReport:pReport="$iReport":"$gReport":"$aReport":"$pReport" $reportName
""")
The point is that the command in the shell must run along with the ", which here frames the values of the variables.
However, no matter how much I tried to screen them:
Put \ or \\ in front of "
Convert the string to 'text' + varibale + 'text'
Put the whole shell line in ' and leave " as is, or with the first point taken into account.
None of this works.
Here is an example output:
java -jar Report.jar settings.xml '2022-07-04 11:00' 01:00 'Offset=01:00;' empty iReport:gReport:aReport:pReport=true:true:true:true App.result
You may notice that for some reason two variables are surrounded by quotation marks ' for themselves, although this is not specified anywhere, which is probably the root of the problem.
Because if me use \", the quotes appear, but not everywhere, in general, me get some mishmash of " and '.
To understand, this is how a groovy file works in the Jenkins pipeline.
Hence my question, under what circumstances do variables start framing themselves '' and how to get rid of it?
Or maybe someone has a different solution to this problem, I would appreciate it.

How can I update column values with the content of a file without interpreting it?

I need to update values in a column when the row matches a certain WHERE clause, using the content of a text file.
The content of the file is javascript code and as such it may contain single quotes, double quotes, slashes and backslashes - out of the top of my mind, it could contain other special characters.
The content of the file cannot be modified.
This has to be done via psql, since the update is automated using bash scripts.
Using the following command - where scriptName is a previously declared bash variable -
psql -U postgres db<<EOF
\set script $(cat $scriptName.js))
UPDATE table SET scriptColumn=:script WHERE nameColumn='$scriptName';
EOF
returns the following error
ERROR: syntax error at or near "{"
LINE 1: ...{//...
^
I would like to treat the content of the file $scriptName.js as plain text, and avoid any interpretation of it.
You should quote the variable:
UPDATE table SET scriptColumn=:'script' WHERE ...
That causes the contents of the variable to be properly escaped as a string literal.
I found a solution to my problem, even though I don't know why it works.
I leave it here in the hope it might be useful to someone else, or that someone more knowledgeable than me will be able to explain why it works now.
In short, setting the variable as a psql parameter did the trick:
psql -U postgres db -v script="$(cat $scriptName.js)"<<EOF
UPDATE table SET scriptColumn=:'script' WHERE nameColumn='$scriptName'
EOF
Not sure how this differs from
psql -U postgres db <<EOF
\set script "$(cat $scriptName.js)"
UPDATE table SET scriptColumn=:'script' WHERE nameColumn='$scriptName'
EOF
which I tried previously and returns the following error:
unterminated quoted string
ERROR: syntax error at or near "//"
LINE 1: // dummy text blahblah
Thanks to everybody who helped!

How can I escape sqlite3 query parameters in bash?

I have a script that boils down to this right now:
#!/bin/bash
SEARCH_PARAM="$1"
SQLITE3_DB="$2"
# Don't inject me please :(
sqlite3 "$SQLITE3_DB" "SELECT foo FROM Bar WHERE bundleId='$SEARCH_PARAM';"
A glaring problem is that the $SEARCH_PARAM value is very vulnerable to SQL injection. Can I fix that from the bash script or do I need to drop in another scripting language, like Python, to get access to query parameters?
How can I escape characters in SQLite via bash shell? is similar but it has fixed string arguments.
In SQL strings, the only character that needs escaping is the single quote, which must be doubled.
This can be done by using pattern substitution in the parameter expansion:
sqlite3 "..." "... bundleId = '${SEARCH_PARAM//\'/\'\'}';"
(Non-standard SQL implementations like MySQL might have additional characters that need escaping.)

Bash script sourcing config file but can't use vars in arithmetic

This is killing me. I have a config file, "myconfig.cfg", with the following content:
SOME_VAR=2
echo "I LOVE THIS"
Then I have a script that I'm trying to run, that sources the config file in order to use the settings in there as variables. I can print them out fine, but when I try to put one into a numeric variable for use in something like a "seq " command, I get this weird "invalid arithmetic operator" error.
Here's the script:
#!/bin/bash
source ./myconfig.cfg
echo "SOME_VAR=${SOME_VAR}"
let someVarNum=${SOME_VAR}
echo "someVarNum=${someVarNum}"
And here's the output:
I LOVE THIS
SOME_VAR=2
")syntax error: invalid arithmetic operator (error token is "
someVarNum=
I've tried countless things that theoretically shouldn't make a difference, and, surprise, they don't. I simply can't figure it out. If I simply take the line "SOME_VAR=2" and put it directly into the script, everything's fine. I'm guessing I'll have to read in the config file line by line, split the strings by "=", and find+create the variables I want to use manually.
The error is precisely as indicated in a comment by #TomFenech. The first line (and possibly all the lines) in myconfig.cfg is terminated with a Windows CR-LF line ending. Bash considers CR to be an ordinary character (not whitespace), so it will set SOME_VAR to the two character string 2CR. (CR is the character with hex code 0x0D. You could see that if you display the file with a hex-dumper: hd myconfig.cfg.)
The let command performs arithmetic on numbers. It also considers the CR to be an ordinary character, but it is neither a digit nor an operator so it complains. Unfortunately, it does not make any attempt to sanitize the display of the character in the error message, so the carriage return is displayed between the two " symbols. Consequently, the end of the error message overwrites the beginning.
Don't create Unix files with a Windows text editor. Or use a utility like dos2unix to fix them once you copy them to the Unix machine.

Robot: Backslash in EXECDIR, Windows path

Underlying problem: I want to enable running robot tests using selenium 2 in a portable Firefox that's stored within EXECDIR.
${firefox_binary}= Evaluate sys.modules['selenium.webdriver.firefox.firefox_binary'].FirefoxBinary('${EXECDIR}${/}Firefox${/}App${/}Firefox${/}Firefox.exe') sys, selenium.webdriver
${firefox_profile}= Evaluate sys.modules['selenium.webdriver.firefox.firefox_profile'].FirefoxProfile('${EXECDIR}${/}Lib${/}SeleniumFirefoxProfile') sys, selenium.webdriver
Create Webdriver Firefox firefox_binary=${firefox_binary} firefox_profile=${firefox_profile}
That works fine if, instead of ${EXECDIR}, I use the actual path.
EXECDIR is something like C:\Users\bart.simpson\workspace\projectname here. The issue is that a backslash, when followed by the b, is converted to the ASCII backslash character. The test log then says:
Evaluating expression 'sys.modules['selenium.webdriver.firefox.firefox_profile'].FirefoxProfile('C:\Users\bart.simpson\workspace\projectname\Lib\SeleniumFirefoxProfile')' failed: OSError: [Errno 20047] Unknown error: 20047: 'C:\\Users\x08art.simpson\\workspace\\projectname\\Lib\\SeleniumFirefoxProfile'
Of course I've tried using ${fixedExecDir}= Replace String ${EXECDIR} '\' '/' and such, but nothing ever changes the outcome.
Ideas? Thanks.
Try treating the path as a raw string literal, by putting an "r" before the quote immediately before ${EXECDIR}:
${firefox_binary}= Evaluate ....FirefoxBinary(r'${EXECDIR}${/}Firefox...')
This should work because the robot variables are substituted before the string is passed to python, so the python interpreter only ever sees the complete string.
If you are unfamiliar with python raw string literals, see this question:
What exactly do “u” and “r” string flags do in Python, and what are raw string literals?

Resources