Python file testing line in BASH program failing with syntax error - python

Hey guys I'm trying to integrate some PY into my shell script and running across
the following error, I though quote should have quoted my variable but it looks
like it's not doing what I expected, can someone help me troubleshoot this?
#!/bin/bash
host='user#localhost'
path='/home/user/file'
python -c "return subprocess.call(['ssh', '$host', 'test -e ' + pipes.quote($path)]) == 0"
File "<string>", line 1
return subprocess.call(['ssh', "user#localhost", 'test -e ' + pipes.quote(/home/jdaniel/sent)]) == 0
^
SyntaxError: invalid syntax

python -c "return subprocess.call(['ssh', '$host', 'test -e ' + pipes.quote(\"$path\")]) == 0"
I would assume
as an aside .. why are you not just calling ssh from the bash? what benefit are you getting by using python here in this fashion? and do you not need to use import subprocess when you use the -c flag?
I would choose to do this whole program either in python or bash ... but mixing them like this feels slightly silly (especially given what your python code does)

You'll need to change this
pipes.quote($path)
to
pipes.quote('$path')
as pipes.quote() is expecting a string
I'd say Its better to use shell instead of python
#!/bin/bash
host='user#localhost'
path='/home/user/file'
ssh -q $host "test -e $path"

Related

linux command pipe with python "-c" flag

I am trying to do a string printing with python -c flag, e.g.
python3 -c "print('Hello World')"
So now I wanna substitute an argument with pipe, e.g. echo "Hello World" | python3 -c "print($1)"
the pipe is to take output from previous command and take it as input to next command, if I am not wrong, this is possible? But I think I got syntax error which I cannot find any source of this
I also bumped into question previously asked, but the solution required python imports and .py file depends on how we run this, I understand but I just wanna get it in a line of command in linux shell
If your input is always single line then you should be able to harness input function for example
echo "Hello World" | python3 -c "print(input().upper())"
would output
HELLO WORLD

How should I embed a python script in a Makefile?

I want to embed a python script in a Makefile
I built a python -c script (below), and it works well in my MacBook Hyper terminal:
% python -c $'from subprocess import getstatusoutput\noutput=getstatusoutput("open --background -a Docker")\nif int(output[0])>0:\n print("Docker desktop failed to launch: exit-code:{}".format(output[0]))'
For reasons I can't yet figure out, this seems to fail if I build a Makefile with it (note: a tab is four spaces... I used tab indentation in the Makefile).
all:
$(shell python -c $'from subprocess import getstatusoutput\noutput=getstatusoutput("open --background -a Docker")\nif int(output[0])>0:\n print("Docker desktop failed to launch: exit-code:{}".format(output[0]))')
Running the make all target...
% make all
/bin/sh: -c: line 0: syntax error near unexpected token `('
/bin/sh: -c: line 0: `python -c from subprocess import getstatusoutput\noutput=getstatusoutput("open --background -a Docker")\nif int(output[0])>0:\n print("Docker desktop failed to launch: exit-code:{}".format(output[0]))''
make: `all' is up to date.
%
I have been struggling with this for a while...
Can someone help explain why make all fails and the best way to fix this python -c command? My shell CLI python -c ... command successfully launches Docker desktop on my MacBook.
I understand there are non-python ways to solve this specific problem... I need a general python Makefile solution.
Using python -c in a Makefile is tricky because of Python's indentation requirements. One simple solution is to use SHELL=/bin/bash if you want to use a Bash "C-style" string:
SHELL=/bin/bash
all:
# python command must be wrapped in single quotes _and_ have double dollar sign in front
python -c $$'from subprocess import getstatusoutput\noutput=getstatusoutput("open --background -a Docker")\nif int(output[0])>0:\n print("Docker desktop failed to launch: exit-code:{}".format(output[0]))'
(Notice how the dollar sign needs to be doubled to escape it. And obviously, this restricts the portability of your Makefile to systems where Bash is available. The $'...' syntax lets you use escape codes like \n and \t within a string, and have them expanded to newline and tab, respectively. This construct specifically requires a leading dollar sign and single quotes around the string - merely '...' does someting slightly different, and $"..." does something entirely different.)
You could also define a make multi-line variable. But in this isolated case, Python is not playing any useful role anyway.
all:
open --background -a Docker
make will terminate with an error message if open fails; printing essentinally the same message from Python seems superfluous. If you want to proceed in spite of the error, you can do
all:
open --background -a Docker || \
echo "Docker desktop failed to launch: exit-code: $$?"
... though I assume failing to fail (sic) from the Python script was just a mistake.
I found a fairly simple way to embed a multiline python script in a Makefile...
Save this as Makefile...
define MULTILINE_PYTHON_SCRIPT
###########################################
# Start multiline python string here...
###########################################
from subprocess import getstatusoutput as gso
print("Here we go:")
for hello_int in [1, 2, 3,]:
print(' Hello World %i' % hello_int)
retval, _ = gso("ls -la")
assert retval==0, "ls command execution failed"
###########################################
# End of multiline python string...
###########################################
endef
export MULTILINE_PYTHON_SCRIPT
EMBEDDED_PY := python -c "$$MULTILINE_PYTHON_SCRIPT"
.PHONY: nothing
nothing:
echo "raw makefile command"
.PHONY: test
test:
$(EMBEDDED_PY)
.PHONY: all
all:
open --background -a Docker
Testing the output:
% make nothing
echo "raw makefile command"
raw makefile command
%
% make test
python -c "$MULTILINE_PYTHON_SCRIPT"
Here we go:
Hello World 1
Hello World 2
Hello World 3
%
%

How to use python -c "code here" with newlines?

The command
python -c "print('hello')"
runs the code inside the quotes successfully, both in Linux (bash) and Windows (cmd.exe).
But how to pass code with newlines, with python -c?
Example: both
python -c "for i in range(10): if i % 2 == 0: print('hello')"
python -c "for i in range(10):\n if i % 2 == 0:\n print('hello')"
fail.
Example use case: I need to send a SSH command (with paramiko) to execute a short Python code on a remote server, so I need to pass one command like
ssh.exec_command('python -c "..."').
You can use bash's $'foo' string syntax to get newlines:
python -c $'for i in range(10):\n if i % 2 == 0:\n print("hello")'
(I'm using single space indents here)
For windows, you really should be using powershell, which has `n as a newline:
python -c "for i in range(10):`n if i % 2 == 0:`n print('hello')"
In cmd.exe, it seems that you can use ^ to escape a newline, however I'm unable to test this currently so you should refer to this question's answers.
You can use a bash "heredoc" (also available ksh, and POSIX shells):
python <<EOF
import numpy as np
print(dir(np))
EOF
While not using -c it is worth mentioning that, if using Bash, you can pipe echoed code directly to python.
echo -e 'for i in range(10):\n if i % 2 == 0:\n print("hello")' | python
Following Aplet123's lead and using using single space indents.
One way could be with exec(), what make strings executable. It looks bad, but it works.
python -c "exec(\"for i in range(10):\n if i % 2 == 0:\n print('hello')\")"

Printing .py file output in command line

I am trying to access a python function from the command line, and I would like to write such a command that will print the output in the terminal. The below doesn't work. What could I change?
python -c 'from laser import Laser; laser = Laser();l = laser.embed_sentences("hello", lang = "en").shape == (1, 1024); print(l)'
(base) ~ % python -c 'print("hello, world")'
hello, world
Printing works fine for me when running python through python -c. Are you sure your terminal isn't truncating your output by omitting the last (and in this case, only) line? You could try creating a single line file (no newline at the end) and then running cat [filename] (which is how I sometimes discover that my terminal is doing this)
-c cmd : program passed in as string (terminates option list)
That is the correct flag to be used. This must be a CLI config issue. Or the script is taking longer than you are expecting to run and it appears no output is generated.
Does python -c 'print("hello")' work?

/bin/sh: 1: Syntax error: word unexpected - Using os.system() from Python

I'm trying to execute a shell command from python. Here's the command :
(flock -n 200 || (echo no; exit 1) && (echo yes; cat /home/user/Desktop/instructions.json; >/home/user/Desktop/instructions.json)) 200>>/home/user/Desktop/instructions.json
I tried os.system() or subprocess.call(); However I always have the same error which is :
/bin/sh: 1: Syntax error: word unexpected
I think the problem is due to parentheses but I'm not sure.
I'm trying to read the file thanks to cat then delete its content IF it's not locked else just echo no and exit.
This command works in shell.
It seems you are trying to lock a file in Python.
In your case you have two opportunities :
You can use the python function fcntl.flock() to directly lock a file
You can also use a simple script sh in which you write #!/bin/sh, at the beginning
To execute a command from python ad it would in the shell, use shell=true as an argument:
subprocess.call("your command", shell=true)
see this post

Categories