Preserve single and double quotes inside bash script - python

I have to run a python script within bash, passing it a string which is stored in a variable... so inside bash I have:
python my_script.py $myvariable
myvariable is a string that can contain single/double quotes which I would preserve (since I make some splits in python script using that quotes). How could I preserve that quotes? Can I escape them somehow before passing to python? I know that I could surround myvariable too with single/double quotes, but I don't know the content of the string, so it would be faulty.

Related

Provide quotes as input command line in python [duplicate]

This question already has answers here:
How to escape single quotes within single quoted strings
(25 answers)
When to wrap quotes around a shell variable?
(5 answers)
Closed last year.
I'm trying to process an input string in a Python script which is taken as a command line argument. This input might contain quotes as well (both single and double is possible) and I'm not able to provide it as input. I tried escaping it (with \), does not work.
Here are the details:
python3 code.py --foo="foo" //works
python3 code.py --foo='foo' //works
python3 code.py --foo='f"o"o' //works
python3 code.py --foo="fo'o'" //works
python3 code.py --foo="fo\"o" //does not work
python3 code.py --foo='fo\'o' //does not work
For my use case, there could also be a mixture of single or double quotes as well. Is there a workaround?
If it matters, here is the relevant code:
import argparse
parser = argparse.ArgumentParser(description="Demo")
parser.add_argument("--foo", required=True)
args = parser.parse_args()
print(args.foo)
Here is what happens when I try and run using input that "does not work":
$ python3 code.py --foo='v\'1'
> ^C
I get a "prompt", which I then exit by ctrl-C. Basically, \ does not escape the (middle) quote, and bash identifies my command as incomplete.
In a unix shell, to easily figure out the exact string you need to send to any commandline argument, you can use Python's shlex.quote():
>>> import shlex
>>> arg = r'''"fo\"o"'''
>>> print(shlex.quote(arg))
'"fo\"o"'
Make sure you wrap the argument with r and triple quotes.
If you happen to have triple quotes in your string, you'll have to manually escape everything without using r.

How to make python 3 understand double backslash? [duplicate]

This question already has answers here:
How to fix "<string> DeprecationWarning: invalid escape sequence" in Python?
(2 answers)
Closed 1 year ago.
So, as SO keeps suggesting me, I do not want to replace double backslashes, I want python to understand them.
I need to copy files from a windows distant directory to my local machine.
For example, a "equivalent" (even if not) in shell (with windows paths):
cp \\directory\subdirectory\file ./mylocalfile
But python does not even understand double backslashes in strings:
source = "\\dir\subdir\file"
print(source)
$ python __main__.py
__main__.py:1: DeprecationWarning: invalid escape sequence \s
source = "\\dir\subdir\file"
\dir\subdir
ile
Is Python able to understand windows paths (with double backslashes) in order to perform file copies ?
You can try this also:
source = r"\dir\subdir\file"
print(source)
# \dir\subdir\file
You can solve this issue by using this raw string also.
What we are doing here is making "\dir\subdir\file" to raw string by using r at first.
You can visit here for some other information.
raw strings are raw string literals that treat backslash (\ ) as a literal character. For example, if we try to print a string with a ā€œ\nā€ inside, it will add one line break. But if we mark it as a raw string, it will simply print out the ā€œ\nā€ as a normal character.

Python3 doesnt detect tuple

I have this input:
python script.py --key '("music","aaa")' --date '("01/01/1990",0,0)'
And I do:
constrain = literal_eval(sys.argv[2])
print(type(constrain))
print(type(sys.argv[4]))
And all outputs are str while they should be tuples. The input cannot be changed!
You're command line should work perfectly from MSYS or Linux, but here you're running it from windows shell.
Windows shell doesn't treat simple quotes as syntatcic. They're passed literally to your python code. To top it all, the double quotes are removed which makes your second arg '(music,aaa)' when passed to python: no way you can literal_eval that. So your input string has to be changed (or your operating system :))
Do this to call your code:
python script.py --key "(""music"",""aaa"")" --date "(""01/01/1990"",0,0)"
You have to quote the arguments and double the quotes in the arguments. And use double quotes exclusively.
EDIT: or even better (would work on both Linux and Windows): use simple quotes inside your arguments, double quotes outside (literal_eval is not json: it understands both simple & double quotes!):
python script.py --key "('music','aaa')" --date "('01/01/1990',0,0)"
now I'm getting:
<type 'tuple'>
<type 'str'>
(you get str because the 4th argument is always a string, you probably forgot to literal_eval it)
and print(constrain) yields:
('music', 'aaa')
(so it's not a python issue, rather a CMD issue)

How does the u and r prefixes work with strings in python?

I know that we can use the r(raw string) and u(unicode) flags before a string to get what we might actually desired. However, I am wondering how these do work with strings. I tried this in the IDLE:
a = r"This is raw string and \n will come as is"
print a
# "This is raw string and \n will come as is"
help(r)
# ..... Will get NameError
help(r"")
# Prints empty
How Python knows that it should treat the r or u in the front of a string as a flag? Or as string literals to be specific? If I want to learn more about what are the string literals and their limitations, how can I learn them?
The u and r prefixes are a part of the string literal, as defined in the python grammar. When the python interpreter parses a textual command in order to understand what the command does, it reads r"foo" as a single string literal with the value "foo". On the other hand, it reads b"foo" as a single bytes literal with an equivalent value.
For more information, you can refer to the literals section in python's documentation. Also, python has an ast module, that allows you to explore the way python parses commands.

Python: Command line arguments not read?

I'm trying to read command line arguments in python in the form:
python myprogram.py string string string
I have tried using sys.argv[1-3] to get each string, but when I have a string such as $unny-Day, it does not process the entire string. How can I process strings like these entirely?
Are you using a shell? $ is a special character in the shell that is interpreted as a shell variable. Since the variable does not exist, it is textually substituted with an empty string.
Try using single quotes around your parameter, like > python myapp.py '$unny-Day'.

Categories