I am trying to convert this script to Python but am having problems with the BASH syntax ${variable}. This does something I do not understand as I have very little experience with BASH scripting. My question is basically,how can I do the dollar brackets variable thing in Python ${variable}. In my case the variable is a number from zero to two-hundred and fifty-five. Please see the BASH script below. I am trying to do the exact same thing in Python.
do
for code in {0..255};
do echo -e "\e[38;05;${code}m $code: Test";
done;
done
Here is my attempt to convert the code to a Python script. Unfortunately, I am still having to call BASH via the os.system() method or function. Please check out my script below. The script does not function the same way though, with changing the text in the BASH shell. The Python script below simply prints out the crazy text below and increments the numbers... :/
#! /usr/bin/env python
import os
def run():
for code in range(0, 255):
os.system('echo -e "\e[38;05;%dm %s Test"' % (code,str(code)))
run()
You can use print command and string formatting to evaluate your variable during the print.
BTW, you can use xrange rather than range in order not to generate all the numbers in your memory, but to yield it one-by-one (for large range)
You can use this:
import os
def run():
for code in range(0, 256):
print "\x1b[38;05;{code}m {code} Test".format(code=code)
run()
You’ll need to use string formatting.
Strangely enough, you already do this in your code (but using the old % syntax instead of the new .format method). I’m not even sure why you think you have to call echo since the string you pass to it is already the string that you are trying to get (if I understand your question right). Just use the print function to output the string.
try this:
#! /usr/bin/env python
import os
def run():
for code in range(0, 255):
os.system('/bin/echo -e "\e[38;05;%dm %s Test"' % (code,str(code)))
run()
the echo is usually both extrnal program and internal command of shell, which can make difference sometime
Related
There is an interactive python script something like
def myfunc():
print("enter value between 1 to 10")
i=int(input())
if(i<1 or i>10):
print("again")
myfunc()
else:
print(i)
I want to store the final output which is print(i) in a shell variable. Something like
python myFile.py | read a
Above query get stuck everytime i run the command. Is it possible to do that?
Even though ( read b | python myFile.py ) | read a defeats the purpose of interactive python function but this doesn't work as well. It works if myfunc() is non-interactive(not expecting user input). The function in reality takes some input, manipulates it, and then output the result in required format. I know it would be much easier to use either python or shell, but since i already wrote the python function, was wondering if it is possible to link both. If yes, is it also possible to add only final value to shell variable rather than all the print()
Same issue happens(terminal gets stuck) when i do
python myFile.py > someFilename
However file someFilename was created even though terminal was unresponsive. It seems shell is starting both the processes at the same time which makes sense. I am guessing if somehow python myfile.py executes independently before opening the pipe it could be possible, but i may be wrong.
If you are working on Linux or other Unix variants, would you please try:
import os
def myfunc():
tty = os.open("/dev/tty", os.O_WRONLY)
os.write(tty, "enter value between 1 to 10\n")
i=int(input())
if(i<1 or i>10):
os.write(tty, "again\n")
myfunc()
else:
print(i)
BTW if your shell is bash, it will be better to say:
read a < <(python myFile.py)
Otherwise read a is invoked in the subshell and the variable a
cannot be referred in the following codes.
I've come across a situation where it would be convenient to use python within a bash script I'm writing. I call some executables within my script, then want to do a bit of light data processing with python, then carry on. It doesn't seem worth it to me to write a dedicated script for the processing.
So what I want to do is something like the following:
# do some stuff in bash script
# write some data into datafile.d
python_fragment= << EOF
f = open("datafile.d")
// do some stuff with opened file
print(result)
EOF
result=$(execute_python_fragment $python_fragment) # <- what I want to do
# do some stuff with result
Basically all I want to do is execute a string containing python code. I could of course just make another file containing the python code and execute that, but I'd prefer not to do so. I could do something like echo $python_fragment > temp_code_file, then execute temp_code_file, but that seems inelegant. I just want to execute the string directly, if that's possible.
What I want to do seems simple enough, but haven't figured it out or found the solution online.
Thanks!
You can run a python command direct from the command line with -c option
python -c 'from foo import hello; print (hello())'
Then with bash you could do something like
result=$(python -c '$python_fragment')
You only have to redirect that here-string/document to python
python <<< "print('Hello')"
or
python <<EOF
print('Hello')
EOF
and encapsulate that in a function
execute_python_fragment() {
python <<< "$1"
}
and now you can do your
result=$(execute_python_fragment "${python_fragment}")
You should also add some kind of error control, input sanitizing... it's up to you the level of security you need in this function.
If the string contains the exact python code, then this simple eval() function works.
Here's a really basic example:
>>> eval("print(2)")
2
Hope that helps.
maybe something like
result=$(echo $python_fragment | python3)
only problem is the heredoc assignment in the question doesn't work either. But https://stackoverflow.com/a/1167849 suggests a way to do it if that is what you want to do:
python_fragment=$(cat <<EOF
print('test message')
EOF
) ;
result=$(echo $python_fragment | python3)
echo result was $result
I am writing a bash script in which a small python script is embedded. I want to pass a variable from python to bash. After a few search I only found method based on os.environ.
I just cannot make it work. Here is my simple test.
#!/bin/bash
export myvar='first'
python - <<EOF
import os
os.environ["myvar"] = "second"
EOF
echo $myvar
I expected it to output second, however it still outputs first. What is wrong with my script? Also is there any way to pass variable without export?
summary
Thanks for all answers. Here is my summary.
A python script embedded inside bash will run as child process which by definition is not able to affect parent bash environment.
The solution is to pass assignment strings out from python and eval it subsequently in bash.
An example is
#!/bin/bash
a=0
b=0
assignment_string=$(python -<<EOF
var1=1
var2=2
print('a={};b={}'.format(var1,var2))
EOF
)
eval $assignment_string
echo $a
echo $b
Unless Python is used to do some kind of operation on the original data, there's no need to import anything. The answer could be as lame as:
myvar=$(python - <<< "print 'second'") ; echo "$myvar"
Suppose for some reason Python is needed to spit out a bunch of bash variables and assignments, or (cautiously) compose code on-the-fly. An eval method:
myvar=first
eval "$(python - <<< "print('myvar=second')" )"
echo "$myvar"
Complementing the useful Cyrus's comment in question, you just can't do it. Here is why,
Setting an environment variable sets it only for the current process and any child processes it launches. os.environ will set it only for the shell that is running to execute the command you provided. When that command finishes, the shell goes away, and so does the environment variable.
You can pretty much do that with a shell script itself and just source it to reflect it on the current shell.
There are a few "dirty" ways of getting something like this done. Here is an example:
#!/bin/bash
myvar=$(python - <<EOF
print "second"
EOF
)
echo "$myvar"
The output of the python process is stored in a bash variable. It gets a bit messy if you want to return more complex stuff, though.
You can make python return val and pass it to bash:
pfile.py
print(100)
bfile.sh
var=$(python pfile.py)
echo "$var"
output: 100
Well, this may not be what you want but one option could be running the other batch commands in python using subprocess
import subprocess
x =400
subprocess.call(["echo", str(x)])
But this is more of a temporary work around. The other solutions are more along what you are looking for.
Hope I was able to help!
I a trying to control the volume of mplayer from a python program. The mplayer program gets started from a bash script:
#!/bin/bash
mkfifo /home/administrator/files/mplayer-control.pipe
/usr/bin/mplayer -slave -input file=/home/administrator/files/mplayer-control.pipe /home/administrator/music/file.mp3
Then I have a GUI written in Python that is supposed to be able to control the volume of the instance of mplayer that is being played. I have tried the following:
os.system('echo "set_property volume $musicvol" > /home/administrator/files/mplayer-control.pipe')
That works if i substitute $musicvol with the numeric value instead, but that is unfortunately of no use. I need to be able to pass the variable.
I would also be able to solve it by invoking a bash script from the Python application, but I can not get that to work either:
subprocess.call("/home/administrator/files/setvolume.sh", executable="bash", shell=True)
You don't need to call os.system and invoke a shell to write that line to the FIFO from your Python script- you can just do:
new_volume = 50
with open("/home/administrator/files/mplayer-control.pipe","w") as fp:
fp.write("set_property volume %d\n" % (new_volume,))
It's not clear to me what you expect to happen in your original python, though - is musicvol set in the environment? If instead it's a Python variable that you want to insert into the string that you're passing, the easiest way is to use the string interpolation operator (%) as I've done in the example above.
In your example of using subprocess.call you don't need the executable or shell keyword arguments if setvolume.sh is executable and has a #! line - you could just do:
subprocess.call("/home/administrator/files/setvolume.sh")
However, it's better to just use open and write in Python as above, I think.
I have a Python function, fooPy() that returns some value. ( int / double or string)
I want to use this value and assign it in a shell script. For example following is the python function:
def fooPy():
return "some string"
#return 10 .. alternatively, it can be an int
fooPy()
In the shell script I tried the following things but none of them work.
fooShell = python fooPy.py
#fooShell = $(python fooPy.py)
#fooShell = echo "$(python fooPy.py)"
You can print your value in Python, like this:
print fooPy()
and in your shell script:
fooShell=$(python fooPy.py)
Be sure not to leave spaces around the = in the shell script.
In your Python code, you need to print the result.
import sys
def fooPy():
return 10 # or whatever
if __name__ == '__main__':
sys.stdout.write("%s\n", fooPy())
Then in the shell, you can do:
fooShell=$(python fooPy.py) # note no space around the '='
Note that I added an if __name__ == '__main__' check in the Python code, to make sure that the printing is done only when your program is run from the command line, not when you import it from the Python interpreter.
I also used sys.stdout.write() instead of print, because
print has different behavior in Python 2 and Python 3,
in "real programs", one should use sys.stdout.write() instead of print anyway :-)
If you want the value from the Python sys.exit statement, it will be in the shell special variable $?.
$ var=$(foo.py)
$ returnval=$?
$ echo $var
Some string
$ echo returnval
10
You should print the value returned by fooPy. The shell substitution reads from stdout. Replace the last line of your program with print fooPy() and then use the second shell pipeline you've mentioned. It should work.