I'm using OSX Mac terminal to run python 2.7.10.
for example:
I have a file called "myfile.py"
so when I want to run it on the terminal it would be like this:
python Desktop/myfile.py
However inside the file I have wrote some functions like
def myFunction(x,y):
return float(x)/y
with this method of running a python script I can not interact with my program and use myFunction to input x and y with different values every time and test myFunction properly.
Thank You,
Try passing -i before the script name
python -i myfile.py
You can learn more about what options are available by running man python.
To quote from the manual:
-i When a script is passed as first argument or the -c option
is used, enter interactive mode after executing the script
or the command. It does not read the $PYTHONSTARTUP file.
This can be useful to inspect global variables or a stack
trace when a script raises an exception.
You can use python -i script.py
This way, script.py is executed and then python enter interactive mode. In interactive mode you can use all functions, classes and variables that was defined in the script.
You can use raw_input() to do that.Your myfile.py code can look like this:
def myFunction(x,y):
return float(x)/y
x = raw_input("Please enter x value: ")
y = raw_input("Please enter y value: ")
print(myFunction(x,y))
Related
I know that I can run a python script from my bash script using the following:
python python_script.py
But what about if I wanted to pass a variable / argument to my python script from my bash script. How can I do that?
Basically bash will work out a filename and then python will upload it, but I need to send the filename from bash to python when I call it.
To execute a python script in a bash script you need to call the same command that you would within a terminal. For instance
> python python_script.py var1 var2
To access these variables within python you will need
import sys
print(sys.argv[0]) # prints python_script.py
print(sys.argv[1]) # prints var1
print(sys.argv[2]) # prints var2
Beside sys.argv, also take a look at the argparse module, which helps define options and arguments for scripts.
The argparse module makes it easy to write user-friendly command-line interfaces.
Use
python python_script.py filename
and in your Python script
import sys
print sys.argv[1]
Embedded option:
Wrap python code in a bash function.
#!/bin/bash
function current_datetime {
python - <<END
import datetime
print datetime.datetime.now()
END
}
# Call it
current_datetime
# Call it and capture the output
DT=$(current_datetime)
echo Current date and time: $DT
Use environment variables, to pass data into to your embedded python script.
#!/bin/bash
function line {
PYTHON_ARG="$1" python - <<END
import os
line_len = int(os.environ['PYTHON_ARG'])
print '-' * line_len
END
}
# Do it one way
line 80
# Do it another way
echo $(line 80)
http://bhfsteve.blogspot.se/2014/07/embedding-python-in-bash-scripts.html
use in the script:
echo $(python python_script.py arg1 arg2) > /dev/null
or
python python_script.py "string arg" > /dev/null
The script will be executed without output.
I have a bash script that calls a small python routine to display a message window. As I need to use killall to stop the python script I can't use the above method as it would then mean running killall python which could take out other python programmes so I use
pythonprog.py "$argument" & # The & returns control straight to the bash script so must be outside the backticks. The preview of this message is showing it without "`" either side of the command for some reason.
As long as the python script will run from the cli by name rather than python pythonprog.py this works within the script. If you need more than one argument just use a space between each one within the quotes.
and take a look at the getopt module.
It works quite good for me!
Print all args without the filename:
for i in range(1, len(sys.argv)):
print(sys.argv[i])
I have written a python program that needs a first command line argument to run from the Terminal. The program can be used to copy a text to the clipboard when it is run with a certain keyword.
~ python3 mclip.py 'agree'
This use case is just an exercise to understand, how I can run a batch file on macOS (or shell script in macOS terminology).
I have created the following shell script and saved it as mclip.command:
#!/usr/bin/env bash
python3 /Users/Andrea_5K/mclip.py
My idea is to execute my shell script from the spotlight input window, passing the argument 'agree'. How can I do that?
On windows the batch file would look like that (mclip.bat):
#py.exe C:\path_to_my_file\mclip.py %*
#pause
I can press WIN-R and type mclip *argument* to run the program. But how can I do the same on a Mac? I cannot type mclip agree in spotlight, that doesn't work like in WIN-R.
#! python3
# mclip.py - A multi-clipboard program.
TEXT = {
'agree': """Yes, I agree. That sounds fine to me.""",
'busy': """Sorry, can we do this later this week or next week?""",
'upsell': """Would you consider making this a monthly donation?""",
}
import sys, pyperclip
if len(sys.argv) < 2:
print('Usage: python mclip.py [keyphrase] - copy phrase text')
sys.exit()
keyphrase = sys.argv[1] # first command line arg is the keyphrase
if keyphrase in TEXT:
pyperclip.copy(TEXT[keyphrase])
print('Text for ' + keyphrase + ' copied to clipboard.')
else:
print('There is no text for ' + keyphrase)
I can get Spotlight to run a script which:
offers you a dialog box with your three options and
then runs your Python script passing the selected option
But I cannot get Spotlight to pass an option to a Python script directly. If that helps, here's how to do it.
Start Script Editor and enter the following code, save it as an app called mclip:
set theArg to choose from list {"Agree", "Busy", "Upsell"} with title "Chooser Dialog" with prompt "Choose option"
tell application "Terminal"
do shell script "/Users/YOURNAME/mclip.py " & theArg
end tell
Note that adding on run argv at the top still doesn't get you any arguments you add within Spotlight - it just plain doesn't seem to want to pass on any arguments you type in the Spotlight dialog.
Now write a Python script called $HOME/mclip.py:
#!/usr/bin/env python3
import os, sys
# Just write the received parameter into a text file on the Desktop to show how it works
file = os.path.expanduser("~/Desktop/result.txt")
with open(file, 'w') as f:
f.write(sys.argv[1])
And make it executable (just necessary one time) with:
chmod +x $HOME/mclip.py
If you now use Spotlight to run mclip, it will pop up a dialog like this:
You may have to answer security questions the first time you run it - depending on your macOS version.
Note that if all your Python script does is copy some text onto the clipboard, you can do that without Python within the Applescript above using:
set the clipboard to "Some funky text"
Just a detail: python is case sensitive. So, if the keys of the dictionary are lower case, the list values in the apple script ought to be lower case to `:D
Assume the shell script (mapIt.command) is:
#!/usr/bin/env bash
python3 /path/to/my/pythonScript.py $#
The $# is interpreted as a list of command line arguments.
I can run the shell script in the MacOS Terminal like that:
sh mapIt.command Streetname Number City
The command line arguments Streetname Number City are forwarded to the python script.
I'm wondering how I can utilize my code on IDLE to work within the macOS Terminal.
For example, I created a function such as:
def multiplication_by_2(x): return 2 * x
and saved the .py file in a desktop folder.
I want to use terminal to test out various cases such as multipication_by_2(100) etc, however I am unsure about which commands to enter in terminal to achieve this.
Any direction toward this would be helpful. Thank you.
Try this at the end of the code:
number = int(str(input("Enter the number you would like to multiply by 2: ")))
multiplication_by_2(number)
This way, you get user input. Then, in the terminal:
$ python3 <filename>.py
Which should produce the output:
Enter the number you would like to multiply: <your input, ex. 100>
200
Hope that solved it!
If you are asking how to send arguments to your program through the command line, python's sys library has a list named argv that holds arguments passed from the command line. Add this to your python file:
from sys import argv
for argument in argv:
print(multipication_by_2(int(argument))) # All arguments are strings by default
Then in the command line, do python file_name.py 20 50 1 and any other number you might want to try, and the program will print its double.
Note: If your command line says python doesn't exist, try python3.
So I'm messing around with the "cmd" module for python, I want a command where you can type "python" and then it opens a python command line. Sort of like how an actual command line would.
Here's my current code.
import cmd
class pythonCmd(cmd.Cmd):
def do_(self, args): # <--- I want this command to have it so you don't type a key word
exec(args)
class cmdLine(cmd.Cmd):
def do_python(self, args):
prompt = pythonCmd()
prompt.prompt = 'python> '
prompt.cmdloop('Python 3.8.2')
prompt = cmdLine()
prompt.prompt = '> '
prompt.cmdloop('Command line starting . . .')
I don't know whether you have to use cmd module or not. But there are much better modules similar to cmd. Modules such as subprocess, os and etc.
I recently used subprocess module, try it.
How about this:
Instead of running your program that opens a shell that can take both python commands and potentially your own commands,
Run python shell, import your program module- you have native python shell that can run python code.
Add support of additional commands by implementing a function like cmd(args) which you can call from the shell. You may need to work on your module to simplify using it in interactive python shell by providing #aliases”to existing functions etc..
With do_shell function you can use it with "!" syntax. For example
> !print("Henlo world")
This would print it, you can use other commands too.
I am using Centos 7.0 and PyDEv in Eclipse. I am trying to pass the variable in Python into c shell script. But I am getting error:
This is my Python script named raw2waveconvert.py
num = 10
print(num)
import subprocess
subprocess.call(["csh", "./test1.csh"])
Output/Error when I run the Python script:
10
num: Undefined variable.
The file test1.csh contains:
#!/bin/csh
set nvar=`/home/nishant/workspace/codec_implement/src/NTTool/raw2waveconvert.py $num`
echo $nvar
Okey, so apparently it's not so easy to find a nice and clear duplicate. This is how it's usually done. You either pass the value as an argument to the script, or via an environmental variable.
The following example shows both ways in action. Of course you can drop whatever you don't like.
import subprocess
import shlex
var = "test"
env_var = "test2"
script = "./var.sh"
#prepare a command (append variable to the scriptname)
command = "{} {}".format(script, var)
#prepare environment variables
environment = {"test_var" : env_var}
#Note: shlex.split splits a textual command into a list suited for subprocess.call
subprocess.call( shlex.split(command), env = environment )
This is corresponding bash script, but from what I've read addressing command line variables is the same, so it should work for both bash and csh set as default shells.
var.sh:
#!/bin/sh
echo "I was called with a command line argument '$1'"
echo "Value of enviormental variable test_var is '$test_var'"
Test:
luk32$ python3 subproc.py
I was called with a command line argument 'test'
Value of enviormental variable test_var is 'test2'
Please note that the python interpreter needs to have appropriate access to the called script. In this case var.sh needs to be executable for the user luk32. Otherwise, you will get Permission denied error.
I also urge to read docs on subprocess. Many other materials use shell=True, I won't discuss it, but I dislike and discourage it. The presented examples should work and be safe.
subprocess.call(..., env=os.environ + {'num': num})
The only way to do what you want here is to export/pass the variable value through the shell environment. Which requires using the env={} dictionary argument.
But it is more likely that what you should do is pass arguments to your script instead of assuming pre-existing variables. Then you would stick num in the array argument to subprocess.call (probably better to use check_call unless you know the script is supposed to fail) and then use $1/etc. as normal.