I'm SSHing to a Windows machine with Paramiko and I'm stressed out by how hard it is to write a command because:
exec_command runs in cmd prompt console, which has limited functionality so I need PowerShell, meaning I should prefix the command with pwsh -c "the command"
However, cmd prompt doesn't support multi-line nor multiple commands naturally, so I need to stick in caret ^s and &&s in the command.
Inside the command I'm calling Python with python -c 'print("hello")\nprint("world")', however I'm already using " for pwsh -c "the command" meaning I need to escape it with backticks `".
This is fiendishly complex and ugly, the code is a mess, it's Python and PowerShell and cmd prompt special characters intertwined at once. I'm almost 100% sure I'm missing something and there is an easier way to do it hence I'm asking whether Paramiko can run do exec_command in PowerShell by default.
The client (Paramiko) has no control over how the command is interpreted. It's about the server.
Windows Win32-OpenSSH definitely can use PowerShell as the default shell.
Related
I would like to include a command to create a 7zip archive withinin a Python script. Since I am working on Windows, I need to pass the command to the powershell console. I am planning to do it with os.system (I am aware that this is not the best way to do it and that I should use subprocess, but I really just need a quick fix and it would not be time effective for me to learn to use a new module in this context).
The following command works if run from the powershell console
&'C:\\Program Files\\7-Zip\\7z' a -mx=0 X:/myarch.zip X:/myarch
So I recreate the same string within python like this:
cmdl = r"&'C:\\Program Files\\7-Zip\\7z' a -mx=0 X:/myarch.zip X:/myarch"
The string is interpreted as follow:
"&'C:\\\\Program Files\\\\7-Zip\\\\7z' a -mx=0 X:/myarch.zip X:/myarch"
Now, if I copy-paste the above string within the powershell console, it runs without problems. However, if I run it within python using os.system(cmdl) I got the following error
"The filename, directory name, or volume label syntax is incorrect"
Why is this the case and how can I fix this issue ?
os.system is meant for executing cmd commands, cmd commands can be ran in powershell maybe after all powershell is a bit advanced but I'm sure that you can't run a cmd command in powershell, henceforth your code is not working.
However a creative solution for executing a powershell command from python(not using python) would be to write your command into a .ps file(powershell script)and then run it using os.startfile()(use this code: os.startfile("script.ps"))
I'm using mingw with msys and mintty on windows. I have a problem that msys and mintty are somehow not flushing output until a command is finished. This means I can't really run any interactive programs.
For example, if I have in C:
printf("Test\n");
the output won't appear until the program has terminated. However, if I have:
printf("Test\n"); fflush(stdout);
then the output appears immediately. If I use msys without mintty or the windows console, then everything works normally.
So my question, what's going on with msys and mintty?
This can be an issue when msys uses the rxvt shell under a number of scenarios. In cases where I see this problem, I ask msys to use the native Windows shell for its console. For example:
C:\MinGW\msys\1.0\msys.bat --no-rxvt
I thought that modern MSYS installations default to using the native shell as MSYS developers seem to prefer it. I have other issues with the native shell that drive me to use the rxvt shell, so I do infrequently run into this issue.
C:\MinGW\msys\1.0\msys.bat --rxvt
I find that the rxvt shell usually works fine except for certain applications that are built as "console" utilities meant to run from a command-line.
The only thing that worked for me was to precede the command with winpty ...
$ winpty java ClassName
It causes unbuffered output to be 3x slower and buffered output to be 5x slower (in my case, with Java).
To always have a command invisibly invoked by winpty ...
$ cd ~
$ pwd -W
... add the following line to .bashrc ...
alias java="winpty java"
... then restart terminal and ignore the (one-time) warning message.
In general, we can use Python to execute Windows's cmd command, for example:
os.system('ipconfig')
but I find that tskill can not be executed by Python, if I use:
os.system('tskill 8684')
to kill a process by its pid, Python will show cmd's error:
'tskill' is not recognized as an internal or external command, operable program or batch file.
but it work well if I use cmd to run the command.
As I know tskill.exe is located in C:\Windows\System32, but this path is not in Python's environment variable. It is maybe the reason, but ipconfig.exe is also in System32, it can be executed.
So why tskill can not be executed by os.system or subprocess.Popen?
I have found the root reason:
My Python is 32-bit, while My PC is Windows7 64-bit, so Python's os.system can not run tskill. If I use Python 64-bit instead, everything is OK.
Use taskkill, which can do pretty much everything as tskill
But if you want to stick to tskill.exe in your scripts/code. Please run the scripts from elevated command prompts. (Right click on cmd.exe and run it as administrator)
os.system('c:\windows\system32\tskill.exe 8684')
In Windows XP when you open cmd.exe you get a console window with a command prompt looking like:
"C:\User and Settings\Staffer\My Documents>" where s> the underscore after the '>' is the cursor.
This is the default for Windows XP. A user might change it using the PROMPT=something or by using set PROMPT=something
In the console window, at the command prompt, entering the internal command "prompt" with no arguments does not return what the current prompt string is.
Is there a command or preferably a Python library that can retrieve what the command prompt is. I didn't want to write a Python module if there was a builtin way of retrieving that string.
The use case for getting the command prompt string is when I use the Python subprocess module to run a python program, and then return to the same console's command prompt while the subprocess is running, I get the cursor on a blank line. I can press Enter and the command prompt will redisplay; but it looks as if hasn't returned from the subprocess yet, which misleads my users.
One solution for the gui part of my app is to run pythonw runapp.py. However I'm left wondering if there's a way to get a clean command prompt when calling subprocess by using already made DOS commands, Python library, proper use of subprocess.Popen() and communicate()?
Not sure if it helps but if you enter "SET" from the command prompt you'll see a list of environment variables, including the current PROMPT (however it won't appear in the list if it's the default prompt).
From the command line:
c:\>echo %prompt%
$P$G
From Python:
>>> import os
>>> os.environ["PROMPT"]
'$P$G'
(http://docs.python.org/library/os.html#process-parameters)
[edit]
Ah, I missed your edit. It sounds like all you want to do is run the script in the background. I believe you are looking for the Windows "start" command with the /b option - http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/start.mspx?mfr=true
I think you are looking for this:
import os
print os.getcwd()
I tried
echo "print 'hello'" | ipython
Which runs the command but ipython immediately exits afterwards.
Any ideas? Thanks!
Edit:
I actually need to pass the command into the interactive Django shell, e.g.:
echo "print 'hello'" | python manage.py shell
so the -i switch gimel suggested doesn't seem to work (the shell still exits after execution)
Use the same flag used by the standard interpreter, -i.
-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, even when sys.stdin does not appear to be a terminal. The PYTHONSTARTUP file is not read.
A Linux example, using the -c command line flag:
$ ipython -i -c 'print "hello, ipython!"'
hello, ipython!
In [2]: print "right here"
right here
In [3]:
Try using the ipy_user_conf.py inside your ~/.ipython
I'm not sure of ipython but the basic python interpreter has a command line parameter to give you the prompt after it executes the file you've given it. I don't have an interpreter handy to tell you what it is but you can get it using python --help. It should do exactly what you want.
Running a custom startup script/profile script with the Django shell was marked as closed: wontfix.
However, there is a shell_plus Django extension discussed in that ticket which seems to do what you want. I haven't had a chance to check it out, but it looks like at the very least it can run a load to auto import all the models of all installed apps (which I usu. find myself doing).
Shell plus.py in django-command-extensions on Google Code
django-command-extensions homepage on Google Code
django_extensions on Github