This thread discusses a way of running Python code from within a Bash script.
Is there any way to do something similar from within a Perl script? i.e. is there any way to run Python code typed on a Perl script? Note that I am not asking about running a Python file from a Perl script. I am asking about running Python code directly typed within the same file that has the Perl script (in the same way that the other thread discussed how to run Perl code from which a Bash script).
Example:
# /bin/perl
use 5.010
my $some_perl_variable = 'hello';
# ... BEGIN PYTHON BLOCK ...
# We are still in the same file. But we are now running Python code
import sys;
print some_perl_variable # Notice that this is a perl variable
for r in range(3):
print r
# ... END PYTHON BLOCK ...
say "We are done with the Perl script!"
say "The output of the Python block is:"
print $output"
1;
Should print:
We are done with the Perl script!
The output of the Python block is:
hello
1
2
3
We are done with the perl script
It sounds like you would be interested in the Inline module. It allows Perl to call code in many other languages, and relies on support modules for each language.
You don't say what you want to do, but you mention Python and there is an Inline::Python.
Yes, the same technique (here-docs) can be used for Perl.
Perl in Bash:
perl <<'END' # note single quotes to avoid $variable interpolation
use 5.010;
say "hello world";
END
or
perl -E'say "hello from perl"'
Bash in Perl:
use autodie; # less error handling
open my $bash, "|-", "bash";
print $bash <<'END'; # single quotes again
echo hello from bash
END
Perl in Bash in Perl:
use autodie; # less error handling
open my $bash, "|-", "bash";
print $bash <<'END'; # single quotes again
perl <<'INNER_END'
use 5.010;
say "hello inception";
INNER_END
END
(which I ironically tested on the commandline, in another heredoc)
Related
I am currently trying to utilize strace to automatically trace a programm 's system calls. To then parse and process the data obtained, I want to use a Python script.
I now wonder, how would I go about calling strace from Python?
Strace is usually called via command line and I don't know of any C library compiled from strace which I could utilize.
What is the general way to simulate an access via command line via Python?
alternatively: are there any tools similar to strace written natively in Python?
I'm thankful for any kind of help.
Nothing, as I'm clueless
You need to use the subprocess module.
It has check_output to read the output and put it in a variable, and check_call to just check the exit code.
If you want to run a shell script you can write it all in a string and set shell=True, otherwise just put the parameters as strings in a list.
import subprocess
# Single process
subprocess.check_output(['fortune', '-m', 'ciao'])
# Run it in a shell
subprocess.check_output('fortune | grep a', shell=True)
Remember that if you run stuff in a shell, if you don't escape properly and allow user data to go in your string, it's easy to make security holes. It is better to not use shell=True.
You can use commands as the following:
import commands
cmd = "strace command"
result = commands.getstatusoutput(cmd)
if result[0] == 0:
print result[1]
else:
print "Something went wrong executing your command"
result[0] contains the return code, and result[1] contains the output.
Python 2 and Python 3 (prior 3.5)
Simply execute:
subprocess.call(["strace", "command"])
Execute and return the output for processing:
output = subprocess.check_output(["strace", "command"])
Reference: https://docs.python.org/2/library/subprocess.html
Python 3.5+
output = subprocess.run(["strace", "command"], caputure_output=True)
Reference: https://docs.python.org/3.7/library/subprocess.html#subprocess.run
I'm looking to write a Lua script and have it also execute something from Python source code as well, as if it went like so:
#!/bin/lua
-- begin lua part
print "Hello"
-- begin python part
Somehow_Executes_Python {
print "Hello" #In python, of course
}
-- End Script
Getting the idea?
I'm not sure if it's even possible, but if I can somehow implement foreign source code in controlled blocks, that would be great. I've seen other things about calling them from a different file/ link/ source, but I'm looking to have it work directly from inside of the lua source code, not from a different file entirely.
The simplest approach would be something along these lines:
#!/usr/bin/env lua
local python = function(code)
local file = assert(io.popen('python', 'w'))
file:write(code)
file:close()
end
-- begin lua part
print "Hello from Lua"
--begin python part
python [=[
print "Hello from Python"
]=]
-- End Script
Line-by-line explanation (without code highlighting, it seems that it is broken for Lua on the SO):
#!/usr/bin/env lua
-- The above is a more sure-fire way to run Lua on linux from a shebang
-- This function runs python code as follows
local python = function(code)
-- It opens a write pipe to the python executable
local file = assert(io.popen('python', 'w'))
-- pipes the code there
file:write(code)
-- and closes the file
file:close()
-- This is an equivalent of running
-- $ python <code.py
-- in the shell.
end
-- Begin Lua part
-- I added "from Lua" to better see in the output what works or not.
print "Hello from Lua"
-- Begin Python part
-- We're calling our python code running function,
-- passing Lua long string to it. This is equivalent of
-- python('print "Hello from Python"')
python [=[
print "Hello from Python"
]=]
-- End Script
I imagine you would like to have at least some interoperability between Lua and Python code. It is a bit more difficult to implement and the way you should do it highly depends on the details of the problem you're actually solving.
The cleanest way would probably to create a socket pair of one kind or another and to make Lua and Python code to talk over it.
Solutions where you may read a variable or call a function from one VM (say Lua) in another (say Python) and vice-versa usually lead to a mess for a multitude of reasons (I tried a lot of them and implemented several myself).
There is a python-lua package called Lupa. Here's the documentation. See if that helps.
I am invoking the bash script from python script.
I want the bash script to add an element to dictionary "d" in the python script
abc3.sh:
#!/bin/bash
rank=1
echo "plugin"
function reg()
{
if [ "$1" == "what" ]; then
python -c 'from framework import data;data(rank)'
echo "iamin"
else
plugin
fi
}
plugin()
{
echo "i am plugin one"
}
reg $1
python file:
import sys,os,subprocess
from collections import *
subprocess.call(["./abc3.sh what"],shell=True,executable='/bin/bash')
def data(rank,check):
d[rank]["CHECK"]=check
print d[1]["CHECK"]
If I understand correctly, you have a python script that runs a shell script, that in turn runs a new python script. And you'd want the second Python script to update a dictionnary in the first script. That will not work like that.
When you run your first python script, it will create a new python process, which will interpret each instruction from your source script.
When it reaches the instruction subprocess.call(["./abc3.sh what"],shell=True,executable='/bin/bash'), it will spawn a new shell (bash) process which will in turn interpret your shell script.
When the shell script reaches python -c <commands>, it invokes a new python process. This process is independant from the initial python process (even if you run the same script file).
Because each of theses scripts will run in a different process, they don't have access to each other data (the OS makes sure that each process is independant from each other, excepted for specific inter-process communications methods).
What you need to do: use some kind of interprocess mechanism, so that the initial python script gets data from the shell script. You may for example read data from the shell standard output, using https://docs.python.org/3/library/subprocess.html#subprocess.check_output
Let's suppose that you have a shell plugin that echoes the value:
echo $1 12
The mockup python script looks like (I'm on windows/MSYS2 BTW, hence the strange paths for a Linux user):
import subprocess
p = subprocess.Popen(args=[r'C:\msys64\usr\bin\sh.exe',"-c","C:/users/jotd/myplugin.sh myarg"],stdout=subprocess.PIPE,stderr=subprocess.PIPE)
o,e= p.communicate()
p.wait()
if len(e):
print("Warning: error found: "+e.decode())
result = o.strip()
d=dict()
d["TEST"] = result
print(d)
it prints the dictionary, proving that argument has been passed to the shell, and went back processed.
Note that stderr has been filtered out to avoid been mixed up with the results, but is printed to the console if occurs.
{'TEST': b'myarg 12'}
I have a small python program that parses a text file and writes the output to another file. Currently, I am writing a bash script to call this program several times, it looks something like:
for i in $(seq 1 100); do
python /home/Documents/myProgram.py myTextFile$i
done
This works fine but I want to know if it is possible to have the python program inside the bash script file so when another user runs the script they don't need to have the python program in their memory; i.e., is it possible to copy and paste the python program into the bash script and run it from within the script itself?
#!/bin/bash
python - 1 2 3 << 'EOF'
import sys
print 'Argument List:', str(sys.argv)
EOF
Output:
Argument List: ['-', '1', '2', '3']
I think you should be able to put:
python << END
[Python code here]
END
But I have not tested this.
for simple scripts you can also run python with the -c option. For example
python -c "x=1; print x; print 'great program eh'"
I wouldn't recommend writing anything too complicated, but it could work for something simple.
Pardon the thread necromancy, but here's a technique that is missing that may be useful to someone.
#!/bin/bash
""":" # Hide bash from python
for i in $(seq 1 100); do
python3 $(readlink -f "$0") myTextFile$i
done
exit
"""
# Python script starts here
import sys
print('Argument List: ', str(sys.argv))
However, I do agree with the general recommendation to just do the loop in Python.
Does a easy to use Ruby to Python bridge exist? Or am I better off using system()?
You could try Masaki Fukushima's library for embedding python in ruby, although it doesn't appear to be maintained. YMMV
With this library, Ruby scripts can directly call arbitrary Python modules. Both extension modules and modules written in Python can be used.
The amusingly named Unholy from the ingenious Why the Lucky Stiff might also be of use:
Compile Ruby to Python bytecode.
And, in addition, translate that
bytecode back to Python source code
using Decompyle (included.)
Requires Ruby 1.9 and Python 2.5.
gem install rubypython
rubypython home page
I don't think there's any way to invoke Python from Ruby without forking a process, via system() or something. The language run times are utterly diferent, they'd need to be in separate processes anyway.
If you want to use Python code like your Python script is a function, try IO.popen .
If you wanted to reverse each string in an array using the python script "reverse.py", your ruby code would be as follows.
strings = ["hello", "my", "name", "is", "jimmy"]
#IO.popen: 1st arg is exactly what you would type into the command line to execute your python script.
#(You can do this for non-python scripts as well.)
pythonPortal = IO.popen("python reverse.py", "w+")
pythonPortal.puts strings #anything you puts will be available to your python script from stdin
pythonPortal.close_write
reversed = []
temp = pythonPortal.gets #everything your python script writes to stdout (usually using 'print') will be available using gets
while temp!= nil
reversed<<temp
temp = pythonPortal.gets
end
puts reversed
Then your python script would look something like this
import sys
def reverse(str):
return str[::-1]
temp = sys.stdin.readlines() #Everything your ruby programs "puts" is available to python through stdin
for item in temp:
print reverse(item[:-1]) #Everything your python script "prints" to stdout is available to the ruby script through .gets
#[:-1] to not include the newline at the end, puts "hello" passes "hello\n" to the python script
Output:
olleh
ym
eman
si
ymmij
For python code to run the interpreter needs to be launched as a process. So system() is your best option.
For calling the python code you could use RPC or network sockets, got for the simplest thing which could possibly work.