Cmd commands from within python script? - python

I just want to enter integrate these two commands from cmd and use them in a python script, but I'm novice in both programming and python. How I can achieve this?
cd C:\
python dumpimages.py http://google.com C:\images\

Use the os.subprocess module.
Note that exec() will also work but it is deprecated in favour of os.subprocess.
Further to my comment above, if all you want to do is retrieve images from a webpage, use GNU wget with the -A flag:
wget -r -P /save/location -A jpeg,jpg,bmp,gif,png http://www.domain.com

I suspect the cd C:\ is not necessary, and once that's gone all you seem to be asking for is a way to launch a python script.
Perhaps all you want is to modify saveimage.py so that it has the hard-coded arguments you want? I don't know what that script is--maybe you can tell us if it's important or you aren't allowed to modify it.

I think you are looking for sys.argv
Try:
import sys
print(sys.argv)
on top of your saveimage.py.
It should print something like:
['C:\saveimage.py', 'http://google.com', 'C:\images\']
You see, sys.argv is a list of strings. The first item is the name of the script itself, the others are the parameters.
Since lists are 0-based, you can access the i-th parameter to the script with sys.argv[i]

Related

remove user site directories from sys.path without "-s" in shebang

The -s argument to the python interpreter prevents sys.path from having user directories:
-s Don't add user site directory to sys.path.
Setting the PYTHONNOUSERSITE environment variable is another way to achieve the same result. Note that setting a user site directory in PYTHONPATH and then calling a script with -s "overrides" the "user site" removal.
If I do not control how a python script is invoked, is there an easy way to remove user directories in a python script or module? I could iterate over sys.path and remove any entries that start with os.environ["HOME"]. Is that the right way? Will I miss any or maybe remove directories that I shouldn't (e.g., what if someone installed python in their home directory, maybe even in ~/.local/... somewhere?)? Is HOME env var the right thing to look for? I don't see any sys.path.usersite that I can use to seed the path scrubbing effort (but see Update 1).
Is there a way to scrub user site directories that's easier than adding that iteration blob at the top of all the python scripts?
A shebang line like so achieves this:
#!/usr/local/bin/python -s
But if one doesn't want to hard-code the path to the python interpreter, one can use this idiom:
#!/usr/bin/env python
Adding arguments (like -s) to the above doesn't work, however, because of the way shebang lines are interpreted on most unix systems (see Update 2):
env: python -s: No such file or directory
There's two subtle variations to this question:
(1) How to emulate what -s does when your script was not invoked with -s (including allowing user site directories if they are in PYTHONPATH)? Maybe the best way(?) for this variation is:
#!/bin/sh
exec python -s << eof
... python code...
eof
Edit The above fails if you want to pass args. This may work better:
#!/bin/sh
exec python -s - "$#" << "eof"
... python code...
eof
Notice the quoted "eof" to avoid having the shell try to do expansions and substitions in the here document body.
As a side note: that also helps if I want the python -S functionality (which does not have an environment variable knob equivalent) or other python option arguments.
(2) How to emulate -s regardless of PYTHONPATH (i.e., remove user site directories even if they are in PYTHONPATH)?
I guess what I was hoping for was a sys variable that points to the user site dir. But I couldn't find one.
Update 1: Thanks to Blender's comment - the variable is in the site module: site.USER_SITE. So you can iterate over sys.path looking for entries rooted in that directory (could have .egg files in your USER_SITE and to emulate -s, you would need to remove those as well).
Update 2: Using env -S is another solution. It allows you to pass arguments to the command spawned by env(1) in a shebang line. FreeBSD has had -S for years (since 6.0). Linux systems that use coreutils (most) have it as of coreutils 8.30 1. It will take a while for Linux distros to get that version of coreutils, so depending on it for portable scripting is probably not prudent yet (now = 2019).
#!/usr/bin/env -S python -s
p.s. See also this older similar thread.

Unable to source .profile in shell script

To start off, I am a complete noob to Debian, Python, and shell scripts, so please speak to me like I am a toddler.
I have a python script I am running through a virtualenv, and I want to execute it via a shell script. Here is what I'm typing in to the terminal to do so:
source .profile
workon cv
cd Desktop/Camera
python main.py
I tried turning this into a shell script, but I receive the error -- source: not found
I've found no answer to my problem, at least not in any terms I can understand. Any advice would be appreciated. Furthermore, before you answer, I also have no idea why it is I need to execute source .profile, I'm simply following a beginner guide for the project which can be found here: https://www.hackster.io/hackerhouse/smart-security-camera-90d7bd
Thanks in advance, and sorry if this is a dumb question.
Best practice for Shell would be shebang at the begging like #Veda suggested.
Execute the shell script using bash like bash shell.sh as the link suggests using relative locations rather than absolute ones
Add a hashbang at the top of your script (should be the first line):
#!/bin/bash
This will ensure you are running your shell-script in bash. Having a shell does not mean it's bash. Not all shells have the source function that you are using (bash has it).
Some prefer the following:
#!/usr/bin/env bash
Since you are a "beginner" I think it does not really matter. The first makes sure it's using the bash in /bin, the second is using the PATH variable to find bash, so the user of your script can provide it's own bash if he/she wants.

How to pass Bash variables as Python arguments

I'm trying to figure out if it is possible to pass values stored in a variable in Bash in as argument values in a python script.
We have a python script that we use to create DNS records in BIND and I've been tasked with cleaning up our outdated DNS database. so far I have something like this in bash:
HOSTNAMES=$(</Users/test/test.txt)
ZONE="zone name here"
IP=$(</Users/test/iptest.txt)
for host in $HOSTNAMES
do
python pytest.py --host $HOSTNAMES --zone $ZONE --ip $IP
done
Unfortunately, I don't have a test environment where I can test this on before I run it on prod and I don't have any experience with Python or Bash scripting. I've mainly only done Powershell scripting, but was wondering if something like what I have above would work.
I've looked around on the forums here but have not found anything that I could make sense of. This post seems to answer my question somewhat, but I'm still not completely sure how this works. How to pass a Bash variable to Python?
Yes, seems to work just fine to me.
To test, I threw together a very quick python script called test.py:
#!/usr/bin/python
import sys
print 'number of arguments: ', len(sys.argv)
#we know sys.argv[0] is the script name, let's look at sys.argv[1]
print sys.argv[1]
Then, in your terminal, set a variable:
>testvar="TESTING"
And try your script, passing the variable into the script:
>python test.py $testvar
>number of arguments: 2
>TESTING
Admittedly I'm not very well-versed in Python, but this did seem to accomplish what you wanted. That said, this assumes the Python script you referenced is already set up to parse the names of the parameters being passed to it - you'll notice my test script does NOT do that, it simply spits out whatever you pass into it.
As long as the variables are exported, they're accessible from Python.
$ export VAR=val
$ python -c "import os; print os.environ['VAR']"
val

Is Bash expanding the "*" character in my python command line parameter?

With the following command in bash:
python myscript.py filename_pattern*
I got two different sys.argv in two Linux machines:
Machine A: sys.argv[1] = filename_pattern*
Machine B: sys.argv[1] = filename_pattern-2013-06-30
Note: filename_pattern-2013-06-30 is a file in my current directory.
One of my colleague tell me that's the evil of bash. But I check the bash in two machines are of the same version, and I checked ~/.bashrc, /etc/bashrc, /etc/profile.d/*.sh too.
Can anyone point out how come the two same version bash act differently ?
It is because in one of your machine, in the folder, there in no file that could match the pattern. So when this happens, the * remains. You can test with one computer, with and without a file match the pattern. There is another reason, the shell option nullglob is disabled. You can read the GNU bash reference for this.
Why you see the different behavior on the two machines is either down to the files present in the directory on both machines or based on the shell options, as pointed out in the comments.
Either way, the way to avoid the problem is to simply surround the argument in quotes so that Bash treats it literally.
python myscript.py "filename_pattern*"
You could handle it in your python program like this example that I found in an introductory book on python. Then it won't matter if bash expands it or not.
import glob
import sys
sys.argv = [item for arg in sys.argv for item in glob.glob(arg)]

Windows 7 - pydoc from cmd

Okay, I'm having one of those moments that makes me question my ability to use a computer. This is not the sort of question I imagined asking as my first SO post, but here goes.
Started on Zed's new "Learn Python the Hard Way" since I've been looking to get back into programming after a 10 year hiatus and python was always what I wanted. This book has really spoken to me. That being said, I'm having a serious issue with pydoc from the command. I've got all the directories in c:/python26 in my system path and I can execute pydoc from the command line just fine regardless of pwd - but it accepts no arguments. Doesn't matter what I type, I just get the standard pydoc output telling me the acceptable arguments.
Any ideas? For what it's worth, I installed ActivePython as per Zed's suggestion.
C:\Users\Chevee>pydoc file
pydoc - the Python documentation tool
pydoc.py <name> ...
Show text documentation on something. <name> may be the name of a
Python keyword, topic, function, module, or package, or a dotted
reference to a class or function within a module or module in a
package. If <name> contains a '\', it is used as the path to a
Python source file to document. If name is 'keywords', 'topics',
or 'modules', a listing of these things is displayed.
pydoc.py -k <keyword>
Search for a keyword in the synopsis lines of all available modules.
pydoc.py -p <port>
Start an HTTP server on the given port on the local machine.
pydoc.py -g
Pop up a graphical interface for finding and serving documentation.
pydoc.py -w <name> ...
Write out the HTML documentation for a module to a file in the current
directory. If <name> contains a '\', it is treated as a filename; if
it names a directory, documentation is written for all the contents.
C:\Users\Chevee>
EDIT: New information, pydoc works just fine in PowerShell. As a linux user, I have no idea why I'm trying to use cmd anyways--but I'd still love to figure out what's up with pydoc and cmd.
EDIT 2: More new information. In cmd...
c:\>python c:/python26/lib/pydoc.py file
...works just fine. Everything works just fine with just pydoc in PowerShell without me worrying about pwd, or extensions or paths.
In Windows Powershell use: python -m pydoc
Examples:
python -m pydoc open
python -m pydoc raw_input
python -m pydoc argv
When you type the name of a file at the windows command prompt, cmd can check the windows registry for the default file association, and use that program to open it. So if the Inkscape installer associated .py files with its own version of python, cmd might preferentially run that and ignore the PATH entirely. See this question.
Based on your second edit, you may have more than one copy of pydoc.py in your path, with the 'wrong' one first such that when it starts up it doesn't have the correct environment in which to execute.
python -m pydoc -k/p/g/w <name>
Syntax for pydoc on windows:
alt1:
C:\path\PythonXX\python.exe C:\path\PythonXX\Lib\pydoc.py -k/p/g/w X:\path\file_to_doc.py
alt2:
python -m pydoc -k/p/g/w X:\path\file_to_doc.py
Of which the latter is the one to prefer, duh. However it requires your windows installation to have registered python to the environment variable "Path".
Setup windows environment variables:
Look at this site for a guide on where to find them. The one you'll be looking for is "Path". If you select Path and click Edit you will see a long row of paths pointing to different folders. The Path's you see here is what allows you to basically reach a veriety of programs in the command line by just entering the name of the program, instead of the whole path to it. So what you want to do here is to locate your Python installation and copy its full path like this: X:\subfolders\PythonXX\ Then you add it to the very end of the long row of Path's like this:
X:\earlier\path\to\something;X:\subfolders\PythonXX\
Notice the ";" that seperates the different paths, make sure not to forget it. When done, click to confirm/Ok, then you would need to restart any cmd.exe that's already open.
The pydoc.py
The thing is that pydoc is a module of the standard python lib, and it's also powered by python. The windows environment, of what I understand, requires you to specify with which program you want to run a certain file with. So to run the pydoc.py-file we would use:
Open file in windows cmd.exe:
X:\subfolders\Python27\python.exe X:\subfolders\Python27\Lib\pydoc.py
pydoc.py's arguments:
pydoc.py comes with a veriety of command line-based features that allows you to enter certain arguments:
-k/p/g/w of which will trigger different behaviours of the pydoc.py-program.
Send arguments to a program through command line:
The syntax to enter these arguments is of what I know always after the x:\pathtofile\filename.suffix, seperated by a simple space. Which gives us the final:
alt1:
X:\subfolders\Python27\python.exe X:\subfolders\Python27\Lib\pydoc.py -w X:\path\file_to_doc.py
alt2 (with python registered to path):
python -m pydoc -w X:\path\file_to_doc.py
The "w"-option will give you a HTML-documentation for the file you want to run documentation on. Notice that pydoc.py will (according to my tests) create the documentation-file in the current working directory. Meaning that you will need to place yourself in a folder of choice before you actually run the command.
The function of -m
Of what I can find, the -m seem to handle registry entries, atleast in the msiexec.exe. I guess it might be used for programs in general this way. So my speculative idea of it is that if "-m" is applied, the pursuing arguments paths will be rewritten so that the .exe-file will be used as a path-reference. But as said, rather speculative.
-m Rewrites all required computer-specific registry entries. (in msiexec.exe) According to Microsoft

Categories

Resources