My project structure:
/Users/user1/home/bashScrpts/shellScript.sh
/Users/user1/home/pyScrpts/pyScrpt.py
From the shell script I want to call a function of pyScrpt.py
Content of
pyScrpt.py
def test():
return sys.argv[1]
shellScript.sh
DATA="testXX"
cmd="import sys;sys.path.insert(0, '/Users/user1/home/pyScrpts/pyScrpt');import pyScrpt; print pyScrpt.test()"
xy=$(python -c \'${cmd}\' "${DATA}")
echo $xy
Error I am getting:
File "<string>", line 1
'import
SyntaxError: EOL while scanning string literal
I don't see whats going wrong here.
Can anyone help me on this??
You just need to replace \' in \'${cmd}\' with double quotes "${cmd}".
Also you should add import sys to your pyScrpt.py.
I have never done this before, but i would hazard a guess that it may be due to the wrong function structure, it should read:
def test()
return sys.argv[1]
Related
I work in a .ipybn file, but i want to import a function from a .py file.
My code is:
from function1 import my_function
However, I get the following error:
SyntaxError: unexpected EOF while parsing
How can I fix this? P.s the files are in the same folder.
You get the error when the file's source code ended before all the blocks in it are completed. For example, if in your file is:
a = input("> ")
if a == 'yes':
print("hello")
As you can see, you tell the program to proceed to print before the if statement is completed.
unexpected EOF while parsing
It was able to open the file, but not parse the content correctly. I would start by checking indentations (spaces vs tabs, # of spaces), quotes, colons.
Something to try is executing python from the command line and importing there. That will eliminate iPython/Jupyter notebook as a variable.
When using bash shell commands it would sometimes be usefull to pipe in python and write a short program and then maybe pipe that into something else. Im not finding a lot of documentation about writing python programs like this although it looks like the "-c" option is the option to use..but when writing even the simplest python program the compiler or should i say interpreter complains. See example below:
$ python -c "
import os
if os.path.isfile("test"):
print "test is a file"
else:
print "test is not a file"
"
When entering the last " the interpretor complains. This runs fine if i put it in a file but if i type it like that on the command line i get errors.
$ python -c "
import os
if os.path.isfile("test"):
print "test is a file"
else:
print "test is not a file"
"
Traceback (most recent call last):
File "<string>", line 4, in <module>
NameError: name 'test' is not defined
I have no idea why the interpretor is complaining here. Does someone know why this isnt working ?
What im really after is something like this:
$ cat somefile | python -c "
import re
check = re.search(pattern, <file input>)
"
I dont know how to access the output of cat in this situation so i just wrote it literally.
You are using double quotes inside double quotes which is ending the quoted string you are passing to python, in a place where you don't expect. Try replacing the outer quotes with single quotes, like I did here:
python -c '
import os
if os.path.isfile("test"):
print "test is a file"
else:
print "test is not a file"
'
If you are using single quotes to terminate the string you are passing to python, make sure to only use double quotes in your code. Additionally, if you can guarantee the availability of Bash as your shell, you can gain added awesome points by using heredoc format instead:
$ python <<EOF
> print "I can put python code here"
> EOF
I can put python code here
Another solution is to escape your inner double quotes so bash doesn't parse them. Like this:
$ python -c "
import os
if os.path.isfile(\"test\"):
print \"test is a file\"
else:
print \"test is not a file\"
"
Either use single quotes to enclose your short program or, if you want to use double quotes to enclose it, escape the quotes with \.
Examples:
1. Escaping quotes
$ python -c "
print \"hello\"
for i in (1,2,3):
print i
"
Output:
hello
1
2
3
2. With single quotes
$ python -c '
print "hello"
for i in (1,2,3):
print i
'
Of course, if you use single quotes to enclose your program and you want to use single quotes inside your python code, you'll have to escape them with \ ;-).
The output is the same.
You can use what is commonly called a "here document" (as in "use the document that is right here"). This avoids all quoting problems when using python -c "..." or python -c '...'
For example:
#!/bin/sh
python <<EOF
print "hello"
for i in (1,2,3):
print i
EOF
The "here document" takes an arbitrary marker ("EOF" is a common choice, but it can be any string you know doesn't occur anywhere else in the data), and accepts all data up unto it finds a line that contains that marker.
I'm trying to write a zsh script that contains a python 1-liner which takes an argument.
#!/bin/zsh
foo_var="foo"
python -c "import sys; print sys.argv" $foo_var
(This isn't my actual code but this is the gist of what I was doing.)
That code outputs the following:
['-c', 'foo']
The one liner got a little longer than I wanted it to, so I put it in a heredoc, like this:
#!/bin/zsh
bar_var="bar"
python << EOF
import sys
print sys.argv
EOF
$bar_var
(Again, not my actual code but same idea.)
which outputs:
['']
./doctest.zsh:14: command not found: bar
I need $bar_var to be on the line as python so it will get passed as an argument, but I can't have anything on the same line as the second 'EOF'. I also can't have anything before the heredoc because python will interpret it as a filename.
Is there a way to work around the mandatory newline after the second EOF, or better yet, is there generally a better way to do this?
(Also this is my first SO post, so please let me know if I've done something wrong in that sense)
This might do what you want:
python - $bar_var << EOF
import sys
print sys.argv
EOF
I'm trying to pass file list to my python script via argument:
python script.py -o aaa -s bbb "filename.txt" "filename2.txt" "file name3.txt"
Unfortunately ArgumentParser is ignoring quotes and instead of giving list of 3 files it gives me list of 4 elements as followed:
1) "filename.txt"
2) "filename2.txt"
3) "file
4) name3.txt"
It completely ignores quotes. How to make it work with quotes?
Hard without seeing what you're using or any code.
Your shell may be interfering, you may need to escape the spaces with \.
Example:
python script.py -o a -f "file1.txt" "file\ 2.csv"
Is hard without code but considering you are using sys.argv[] you can easily pass the file arguments with quotes like when you need a file or argv with blank spaces: python script.py "myFile.txt" "otherFile.jpeg"
Try this simple code to understand:
import sys
for n, p in enumerate(sys.argv):
print("Parameter: %d = %s") % (n, p))`
You can see that first argv is the file name you are running.
It looks like that this is not python's fault. I'm calling python script from inside of bash script and this make mess with quotes as parameters.
I am a beginner at Python. Below is the testing code for Python's command line args. If executing from command line with different parameter formats, I get different results, but it feels strange, can anyone help me understand why?
1, $test.py d:\ --> this seems ok for os.walk call
2, $test.py 'd:\' --> this will cause nothing output
BTW: I used Python 2.7.3
Test code:
import os
import sys
if __name__ == '__main__':
argMock = 'D:\\'
path = len(sys.argv) > 1 and sys.argv[1] or argMock
for root, dirs, files in os.walk(path):
for name in files:
print name
Maresh and Jakub's answers are incorrect.
The command line argument d:\ will become the string "d:\".
The command line argument 'd:\' will become the string "'d:\'".
Running the following with input 'D:\':
print sys.argv[1] # $test.py 'D:\\'
print argMock
yields:
'D:\\'
D:\
The issue is that putting quote marks around something that is already considered a string will just include the quote marks as part of the string.
The problem doesn't come from your program, it comes from the shell interpretation.
When you write 'd:\' your shell interprets the backslash as an escaping command for the next caracter. Therefore you must escape the backslash like this: 'd:\\'