I have access to a machine with a minimal cygwin installation, and the Windows version of python. I need to run some python scripts there, however python requires Windows paths. I can use cygpath -w, on the arguments that I provide, however further unix/cygwin paths are included in numerous other scripts which are subsequently invoked.
Is there a way to tell Windows python to accept unix/cygwin paths?
No, Windows python has no suport for Cygwin paths, but Cygwin does have its own Python. If you can't add that to the existing Cygwin install, you might want to consider doing a user-specific Cygwin install into a directory that you're allowed to write to.
There is a way to obtain limited Cygwin path support for Windows programs, although I suspect this isn't an option for you either: install Cygwin into C:\, so that a Cygwin /path is equivalent to C:\path. This relies on the fact that the Windows API (albeit not all Windows programs) accepts both backslashes and slashes as path separators, and that it considers absolute paths without drive letter as referring to the system drive (i.e. C:).
Obviously this won't work for Cygwin paths that point to other drives (via the Cygwin mount table). It also won't work for any programs that use / (rather than -) to introduce options, which includes most built-in Windows command-line tools. But it does usually work for cross-platform tools such as Python.
Yet another option is to use MSYS instead of Cygwin, which is a fork of an old Cygwin version, whereby its most distinctive feature is that it automatically translates POSIX paths to Windows paths when invoking Windows programs. Note however, that this approach has its pitfalls too, because it isn't always clear whether an argument is a path or not. Hence, sometimes it will fail to translate a path or wrongly change an argument that isn't a path.
Create a file named wpython and save it somewhere for example in /bin:
#!/bin/bash
path=$1
shift # Remove filepath from other args to pass them further
python.exe $(cygpath -w $path) $# # Call python.exe with Windows path and passed args
So then use it like this:
#!/usr/bin/env wpython
print(123)
Don't forget to make both file executable with: chmod +x filename
P.S.: Soultion based on this blog post.
Related
I have some small utility scripts written in Python that I want to be usable on both Windows and Linux. I want to avoid having to explicitly invoke the Python interpreter. Is there an easy way to point shebang notation to the correct locations on both Windows and Linux? If not, is there another way to allow implicit invocation of the Python interpreter on both Windows and Linux without having to modify the script when transferring between operating systems?
Edit: The shebang support on Windows is provided Cygwin, but I want to use the native Windows Python interpreter on Windows, not the Cygwin one.
Edit # 2: It appears that shebang notation overrides file associations in Cygwin terminals. I guess I could just uninstall Cygwin Python and symlink /usr/bin/python to Windows-native Python.
Read up on the Python Launcher for Windows in the docs, which was initially described in PEP 397. It lets
you define custom shebang configurations in "py.ini" (e.g. to use pypy),
and out of the box you can use virtual shebangs such as #!/usr/bin/env python3, or shebangs with real paths such as #!"C:\Python33\python.exe". (Quoting is required for paths containing spaces.) You can also add command-line options to a shebang. For example, the following shebang adds the option to enter interactive mode after the script terminates: #!/usr/bin/python3 -i.
The installer associates .py (console) and .pyw (GUI) script file types with the respectively named launchers, py.exe and pyw.exe, in order to enable shebang support for scripts in Windows. For an all-users installation, the launchers are installed to the Windows folder (i.e. %SystemRoot%). For a per-user installation, you may need to manually add the installation directory to PATH in order to use py.exe in the shell (*). Then from the command line you can run Python via py -2, py -3, py -2.6, py -3.3-32 (32-bit), and so on. The launcher is handy when combined with -m to run a module as a script using a particular version of the interpreter, e.g. py -3 -m pip install.
(*) The new installer in 3.5+ defaults to "%LocalAppData%\Programs\Python\Launcher" for a per-user installation of the launcher, instead of installing it beside "python.exe", and it automatically adds this directory to PATH.
Unless you are using cygwin, windows has no shebang support. However, when you install python, it add as file association for .py files. If you put just the name of your script on the command line, or double click it in windows explorer, then it will run through python.
What I do is include a #!/usr/bin/env python shebang in my scripts. This allows for shebang support on linux. If you run it on a windows machine with python installed, then the file association should be there, and it will run as well.
Short answer:
The easiest way is to install git for windows wich comes with GitBash. Then add shebang lines in your scripts to indicate they should be run with python when executed.
#!/usr/bin/env python
More info:
Unlike Cygwin, git bash uses your native windows applications and lets you use bash scripts without any configuration.
It will automatically treat any file with a shebang line as executable the same way Linux shells do.
eg: #!/usr/bin/env php or #!/usr/bin/env node or any other application you want will work as long as you add the paths to your windows ENV path.
You can edit env vars in windows by hitting start and typing env should be the first option.
Git bash also installs git and hooks it up with a credentials manager for you and makes it super easy to sign into 2fa-enabled svn services and a ton of other handy developer features.
Git bash is IMO a must on every developer's machine.
Another option:
Install WSL (Windows Subsystem for Linux) which will work the same.
WSL also lets you install native Linux versions of all your command line applications if you prefer.
Linux binaries will take precedence over windows ones if installed but you can still choose to run the windows version of commands any time you want by specifically adding .exe on the end.
Install pywin32. One of the nice thing is it setups the file association of *.py to the python interpreter.
sorry for open old topic.
I create one file py.cmd and place it in the C:\Windows\System32 folder
py.bat:
#(
#set /p shebang=
)<%1
#set shebang=%shebang:#! =%
#%shebang% %1 %2 %3 %4 %5 %6 %7 %8 %9
py.bat file explain:
Get the first line from *.py file
Remove shebang characters "#! "
Run python file using shebang python path
All windows python script must start with shebang line as the first line in the code:
#! c:\Python27\python.exe
or
#! c:\Python37\python.exe
Then run it:
cmd> py SomePyFile.py param1 param1 paramX
Not with shebang ... but you might be able to set up a file association, see this SO question which deals with Perl and the associated answers which will also be pertinent as there's known problems with Windows and stdin/out redirection...
I have several packages on my windows python environment and I would like to use them inside Cygwin. Can I setup a virtual environment linked to the files used for the windows' python or do I have to copy the files?
Older Cygwin was written with its stdin, stdout, stderr bound to Windows i.e. it was a Win32 console program. Then it was possible to run Windows version of Python as:
/cygdrive/c/Python27/python.exe
You could even have added /cygdrive/.../Pythonxx to your path variable.
Newer versions are written with implemented their own terminals and when you run an Win32 console app like Python it freezes.
Even running it under "cmd" run inside cygwin won't work.
Half an answer is to run it always in interactive mode, then it works a little. Eg.
/cygdrive/c/Python27/python.exe -i program.py
or just for shell
/cygdrive/c/Python27/python.exe -i
You can try playing around under cygwins options, and change a terminal which it currently emulates, to see whether it will do you any good.
Running Windows version of Python under cygwin, if you have older one, will be like you are still in Windows but using Unix console.
I think that is not something you would like to do anyway,
but mentioned it just in case.
I would like to do just that very much, but well, on newer Cygwins it doesn't work.
Then all modules are still there. And you're still in Cygwin.
To access modules which are in Windows version of Python from Cygwins version you add the Windows site-packages to the Python path variable.
On top of your program do:
import sys
sys.path.insert(0, "/cygdrive/c/Python27/lib/site-packages")
Then you can import them normally. But, this isn't exactly advisable.
For example, all modules that depend on windows paths could have great problems.
Or those written in C wouldn't exactly like been called from Cygwin.
Especially when Cygwin's Python version number and Windows's one aren't the same.
I tried with pyaudio, it collosaly crashed.
Some of them (mostly the little ones) will work just fine.
But, IMPORTANT NOTE here is, depending on the place you insert your Windows site-packages path the directory will be searched.
If you put it in place 0, Python will look at it firstly.
Then, it is perhaps better to use:
sys.path.append("/cygdrive/c/Python27/lib/site-packages")
If some package is packed into an EGG or ZIP archive, you will have to add it separately to the path.
The same goes for subdirectories. You try and keep thumbs up.
If you don't want to do that, you can:
import os
wd = os.getcwd()
os.chdir("/cygdrive/c/Python27/lib/site-packages")
# Your Windows imports here
os.chdir(wd)
Sometimes you will have to do both.
You can add even a check, so that your program works in both environments nicely:
if sys.platform=="cygwin": ...
It will work without a check, but it is stupid to bother Python with twice added same directory into the path.
Copying the packages will save you from these extra lines of code, but the problems I mentioned above will remain the same.
Never the less, if the modules are small, copy them, if not, do as I said, but be aware that it's not exactly something that is supposed to be done.
First of all I know The path points to the executable file. What I'm asking is in which directory it points?
I'm very new at python. I works on PHP, and now I'm giving Python a try.
I'm configuring my apache-2.2 with python. I have configured my cgi-bin directory. My problem is I installed Python2.7 on a very different location, and dont know how to point that "#!usr/" path to the exact location where python.exe is.
Thanks,
Kamil
The directory it points to is... /usr/? you define the path and THEN the executable, like so: #!/usr/bin/python3 where python3 is the executable and the path is /usr/bin/, standard python directory if you think about it.. most binaries are stored in /bin or /usr/bin.
I'm assuming you're rocking a windows machine tho since you mentioned .exe.
So do: #!E:/python-installed/python.exe -u
Some docs:
http://www.imladris.com/Scripts/PythonForWindows.html
Provided running python or python2 does the right thing (preferably test this as the user the cgi script will run as if you can), the convention is to use the program env - which can search $PATH for an executable instead of hard coding a path. env is a standard program on any Unix-like system, which is always in /usr/bin unless your base system is very strange, so you can do this:
#!/usr/bin/env python
According to this previous answer, this would cause the line to be ignored on a Windows machine, which may be what you want - it will cause Apache to revert to other ways to find an appropriate interpreter, which seems to include the value of a registry key (at HKEY_CLASSES_ROOT\.cgi\Shell\ExecCGI\Commandfor cgi files, and change the extension as appropriate), and likely includes Windows' standard lookup rules if that key is unset.
I need scipy on cygwin, so I figured the quickest way to make it work would have been installing enthought python. However, I then realized I have to make cygwin aware of enthought before I can use it, e.g. so that calling Python from the cygwin shell I get the enthought python (with scipy) rather than the cygwin one.
How do I do that?
I can guess my question is easy, but I'm just learning about all of this and so please be patient :-)
Think about uninstalling the cygwin version of Python, at least to start with. It's easy enough to reinstall later.
Copy your Windows path.
Install the Windows version of Enthought Python.
Examine the new Windows path. The new entries probably have to be transferred to your bash shell in cygwin. (I haven't seen Enthought. There might be more than one new path entry.) But test without changing the bash path, just to be sure.
Add the new path entries to, umm, .bashrc, I think. The path under cygwin will be a colon delimited string. You'll need to use the /cygdrive path; expect to use an entry like this to put Entought in the path.
/cygdrive/c/Program Files/Enthought
To actually do that, edit .bashrc, and put these two lines (or something like them) at the end.
PATH=$PATH:/cygdrive/c/Program\ Files/Enthought
export PATH
Note that the backslash allows proper interpretation of spaces in file paths. The export statement guarantees that programs called by bash will also include that path.
Just put the directory with enthought python before the directory with Cygwin's python in your path. If both are in the same directory, use ln to create a symbolic link, store it in another directory, and place it higher in your path. The previous answer has instructions to add it to your path.
I'm using Django 1.5 & Python 2.7 on Windows + Cygwin. The following command gives me an error in bash shell
$ python /cygdrive/c/Python27/Lib/site-packages/django/bin/django-admin.py
Error:
C:\Python27\python.exe: can't open file '/cygdrive/c/Python27/Lib/site-packages/django/bin/django-admin.py': [Errno 2] No such file or directory
However this works
$ python c:/Python27/Lib/site-packages/django/bin/django-admin.py
I've seen lots of similar questions on django-admin.py errors but none specifically about this.
So what's the difference between python c:\somefile.py & python /cygdrive/c/somefile.py in a bash shell on Cygwin
As others have noted, part of the problem here is that you're calling Windows Python from Cygwin. This is an odd thing to do, as you hit strange behaviour like this, but it can work with care.
When you call Python from Cygwin - and this is the case for both Cygwin Python and Windows Python - the path you pass will be given as-is to Python to handle. That means Python must know how to handle that kind of path. For example, if you pass the following:
C:\path\to\script.py - Windows Python knows how to handle this, while Cygwin Python is likely to get confused. That said, if you type this into a Cygwin shell, those backslashes are liable to be interpreted as escape characters, and whether they are or not depends on some relatively complicated rules. Avoid, if you're playing around in Cygwin.
'C:\path\to\script.py' - Those quotes will be stripped by Cygwin's bash shell, while stopping the backslashes being taken as escape characters, so this would work fine for calling Windows Python from Cygwin. Running from a Windows command line or similar will cause problems, though, as Windows doesn't handle single quotes.
/cygdrive/c/path/to/script.py - This is the path from the point of view of any Cygwin program, such as Cygwin Python. It works perfectly for Cygwin Python, but not at all for Windows Python.
C:/path/to/script.py - It's not very well known, but backslashes in Windows paths can be replaced with forward slashes, and any well-behaved Windows program should handle that just fine: they're explicitly allowed by Windows. In particular, Windows Python has no problem with them whatsoever, and Cygwin's bash shell won't try to be clever with the forward slashes. You can therefore use this kind of path anywhere you would call Windows Python.
$(cygpath -w /cygdrive/c/path/to/script.py) - cygpath is a Cygwin utility to convert between different path styles; called with a -w option, it converts a Cygwin path to a Windows path. The $(...) indicated that Cygwin's bash shell should replace the text with the result of running the command, so if this were given as the argument to Windows Python called from a Cygwin bash shell, Windows Python would receive a Windows path it can use.
path/to/script.py - This is a relative path, so you need to call it from a suitable directory. It's the first version that will work for both Cygwin and Windows Python, and called from both a Cygwin shell and a Windows command line.
As you can see, paths are complicated, particularly when you're using Cygwin and Windows tools together.
As a general rule, the safest thing is to stick to using one or the other if possible (so only use Cygwin Python from a Cygwin shell, and only use Windows Python from a Windows command line). If that's not possible, the next best is to use cygpath whenever you're calling a Windows program from Cygwin or the other way around - running cygpath -w /cygdrive/c/Windows will give c:\windows; running cygpath 'c:\Windows' will print /cygdrive/c/Windows.
You seem to have Python installed in C: instead of in /usr/bin/python or similar. I'm guessing you installed the Windows port of Python from python.org, and not the Cygwin python package. In this case, the python executable is not using Cygwin (it's running native) and is expecting Windows-formatted path names.
Further, your Django seems to be installed in your Windows Python install. Cygwin is probably completely out of the loop.
Well, nothing should be different:
hgs15624#ESCLT0116 ~
$ python /cygdrive/c/test.py
Hello
hgs15624#ESCLT0116 ~
$ python c:/test.py
Hello
I guess you've looked for odd permissions.
Edit: the below was just referring to a typo in the question.
The error says:
/cygdrive/c/Python27/Lib/sitepackages/django/bin/django-admin.py
Did you miss the hyphen in site-packages?