配置IPython以使用Powershell而不是cmd [英] Configure IPython to use powershell instead of cmd

查看:74
本文介绍了配置IPython以使用Powershell而不是cmd的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

搜索了此内容,似乎找不到任何已经问过的人,所以去了.

Searched for this, and couldn't seem to find anyone who'd already asked, so here goes.

我开始在Windows 7上切换为IPython作为我的外壳,我想对其进行配置,以使将命令传递给系统外壳的bang magic(!cmd)使用PowerShell而不是cmd.exe,这样我就可以利用MS所做的增强,而不必将%COMSPEC%更改为PowerShell(我的公司仍然使用几个基于CMD的.BAT进行自动化,我不想打破那些.)

I'm starting to switch over to IPython as my go-to shell on Windows 7, and I'd like to configure it so that the bang magic (!cmd) to pass a command to the system shell uses PowerShell instead of cmd.exe, so that I can take advantage of the enhancements MS has made, but without having to change my %COMSPEC% to PowerShell (my company still uses several CMD-based .BATs for automation, and I don't want to break those).

我将在此处顶部提问,因为答案可能不需要以下任何信息:

I'll post my questions here at the top, since the answer may not require any of the information below:

  1. 我想念什么吗?是否可以使用IPython中的配置文件来指定系统命令解释器?
  2. 如果!1,是否有一种方法无法从PowerShell内部使用该进程本地的Machine-scope环境变量启动子进程?

调查/测试

在IPython代码中,我看到它正在使用os.system()而不是subprocess.call()来将命令发送到外壳.这使事情变得更加复杂,因为os.system *仅使用COMSPEC,而在subprocess *中,您可以指定要使用的可执行文件.

Investigation/Testing

Looking through the IPython code, I see that it's using os.system() to send the command to the shell, rather than subprocess.call(). That makes things somewhat more complicated, since os.system* just uses COMSPEC, where with subprocess*, you can specify the executable to use.

我尝试加载PowerShell,设置$env:comspec变量,然后从该Shell中启动IPython,但是即使COMSPEC似乎已设置,即使在IPython中,它似乎仍在使用CMD:

I tried loading PowerShell, setting the $env:comspec variable, then starting IPython from within that shell, but even though COMSPEC appears set, even within IPython, it looks like CMD is still being used:

[PS] C:\> $env:comspec
C:\Windows\system32\cmd.exe
[PS] C:\> $env:comspec = 'powershell.exe'
[PS] C:\> $env:comspec
powershell.exe
[PS] C:\> & 'C:\Python33\Scripts\ipython3.exe'
Python 3.3.2 (v3.3.2:d047928ae3f6, May 16 2013, 00:03:43) [MSC v.1600 32 bit (Intel)]
Type "copyright", "credits" or "license" for more information.

IPython 1.1.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: import os; os.getenv('comspec')
Out[1]: 'powershell.exe'

In [2]: !gci
'gci' is not recognized as an internal or external command,
operable program or batch file.

In [3]: os.system('gci')
'gci' is not recognized as an internal or external command,
operable program or batch file.
Out[3]: 1

好像将本地修改的COMSPEC传递给IPython(作为进行本地更改的PowerShell进程的子代),但是os.system看起来仍在使用持久性设置.

That looks like the locally-modified COMSPEC is being passed to IPython (as a child of the PowerShell process that made the local change), but os.system looks to still be using the persistent setting.

我尝试使用[Environment]::SetEnvironmentVariable("ComSpec", 'powershell.exe', [System.EnvironmentVariableTarget]::User)进行了类似的操作,以防万一我只能更改User-scope环境变量,但这还是行不通的(与上面的结果相同-os.getenv('ComSpec')显示了powershell,但!-ed命令发送到CMD).

I tried something similar, using [Environment]::SetEnvironmentVariable("ComSpec", 'powershell.exe', [System.EnvironmentVariableTarget]::User), in case I could get away with only changing a User-scope environment variable, but that didn't work, either (same results as above - os.getenv('ComSpec') shows powershell, but !-ed commands are sent to CMD).

由于前面提到的原因,更改Machine-scope环境变量似乎可以满足我的要求,但对我来说不是有效的解决方案.

Changing the Machine-scope environment variable seems to do what I want it to, but isn't a valid solution to me, for reasons mentioned before.

[PS] C:\> $env:comspec
C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe
[PS] C:\> [Environment]::GetEnvironmentVariable('ComSpec','User')
[PS] C:\> [Environment]::GetEnvironmentVariable('ComSpec','Machine')
C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe
[PS] C:\> & 'C:\Python33\Scripts\ipython3.exe'
Python 3.3.2 (v3.3.2:d047928ae3f6, May 16 2013, 00:03:43) [MSC v.1600 32 bit (Intel)]
Type "copyright", "credits" or "license" for more information.

IPython 1.1.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: !gci env:ComSpec

Name                           Value
----                           -----
ComSpec                        C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe

由于这不是一个可行的持续解决方案,因此我通过修改ConEmu *中的设置进行了更多测试.通过设置 Settings> Startup中的 Explicit可执行文件将子进程的ComSpec环境变量设置为选定值 *标志,我能够做到这一点而无需更改全局变量> ComSpec ,并提供了powershell.exe的路径,但是我不确定这是否会对使用ConEmu打开的CMD控制台产生负面影响,因为该设置是全局的(在ConEmu中).这就是导致我问上述问题2的原因,因为我不确定如何在PowerShell中设置进程/子本地的机器范围环境变量(如果可能的话).

Since that's not a viable ongoing solution, I tested some more by tinkering with settings in ConEmu*. I was able to do this without changing the global variable by setting the Explicit executable and Set ComSpec environment variable for child processes to selected value* flags in Settings > Startup > ComSpec, and providing the path to powershell.exe, but I'm not sure if that will have a negative impact on CMD consoles opened using ConEmu, since that setting is global (within ConEmu). This is what led me to ask Question 2, above, since I'm not sure how to set process/child-local, Machine-scope environment variables in PowerShell (if such a thing is even possible).

最后,我的梦想目标是让IPython通过配置文件支持命令解释器的规范,但是要做到这一点,os.system()不能成为常规用法.我打算修补一下,在我的本地副本中将其替换为subprocess.call()(请将此 GitHub ),但是我对Python如此陌生,因此不能肯定地说,如果有条件的Windows端也使用了该更改,那么其他任何事情都不会中断.

In the end, my dream goal would be for IPython to support specification of a command-shell interpreter via a config file, but to do that, os.system() can't be what's used. I'm planning to tinker with replacing it with subprocess.call() in my local copy (a'la this Python Doc) to test, but if anyone's already played with that, or if there's a sufficient advantage to the current model over using subprocess that I'm not aware of, I'd be glad to hear of it. It looks like this is already being done for non-Windows systems (GitHub), but I'm new enough to Python on this scale that I can't say for certain that nothing else would break if that change were used on the Windows side of the conditional, as well.

Gah!显然,必须拥有10多个声誉才能正确记录问题.这是我不允许在上面发布的链接:

Gah! Have to have 10+ reputation to properly document questions, apparently. Here are the links that I wasn't allowed to post above:

  • os.system-docs.python.org/3.3/library/os.html#os.system
  • 子流程-docs.python.org/3.3/library/subprocess.html
  • ConEmu-code.google.com/p/conemu-maximus5/

推荐答案

您可以使用IPython的脚本魔术来执行PowerShell命令.

You can use IPython's script magics to execute PowerShell commands.

在您的 IPython配置文件中,修改ipython_config.py以包括行:

In your IPython profile, modify ipython_config.py to include the lines:

c.ScriptMagics.script_magics = ['powershell']
c.ScriptMagics.script_paths = {
        'powershell':'powershell.exe -noprofile -command -'}

-command -告诉PowerShell执行命令stdin文本.如果需要加载PS配置文件,则可以省去-noprofile,但这会比较慢.

-command - tells PowerShell to execute the stdin text as the command. You can leave out the -noprofile if you need to load your PS profile, but it will be slower.

然后您可以将%%powershell用作脚本单元魔术.

In [1]: %%powershell
   ...: 1..5
1
2
3
4
5

自定义魔法

为了使它更易于使用,我定义了自己的魔术函数来处理带有行魔术和单元魔术的PowerShell命令. (请参阅:定义自己的魔术 ),可以通过将脚本放在IPython配置文件的启动文件夹中来自动加载. (即~\.ipython\profile_default\startup\05-powershell_magic.py)

Custom Magics

To make it a little easier to use, I defined my own magic function to handle PowerShell commands with both line and cell magics. (see: defining your own magics) This can be loaded automatically by placing the script in your IPython profile's startup folder. (i.e. ~\.ipython\profile_default\startup\05-powershell_magic.py)

from IPython.core.magic import register_line_cell_magic

from IPython import get_ipython
ipython = get_ipython()

@register_line_cell_magic
def ps(line, cell=None):
    "Magic that works both as %ps and as %%ps" 
    if cell is None:
        ipython.run_cell_magic('powershell', '--out posh_output' ,line)
        return posh_output.splitlines()
    else:
        return ipython.run_cell_magic('powershell', line, cell)

用法示例

要使用%ps换行符并将输出返回到变量,请执行以下操作:

Usage Examples

To use the %ps line magic and return the output to a variable:

In [1]: ps_version = %ps $PSVersionTable.PSVersion.ToString()

In [2]: print(ps_version)
['2.0']

要使用%%ps单元格魔术并将其输出到控制台,请执行以下操作:

To use the %%ps cell magic and output to the console:

In [3]: %%ps
   ...: gci c:\

    Directory: C:\

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d-r--         10/2/2013  10:39 AM            Program Files
d-r--         12/6/2013   1:44 PM            Program Files (x86)
d----          2/6/2014   4:33 PM            TEMP
d-r--        11/27/2013  11:10 AM            Users
d----         1/13/2014  11:21 AM            Windows

细胞魔术可以使用--out <variable name>将输出发送到变量:

Cell magics can send output to a variable with --out <variable name>:

In [4]: %%ps --out process_name_id
   ...: $procs = gps| select Name, ID
   ...: $procs| ConvertTo-Csv -NoType| select -skip 1

In [5]: import csv

In [6]: list(csv.reader(process_name_id.splitlines()))
Out[6]:
[['7+ Taskbar Numberer', '3400'],
 ['acrotray', '3668'],
 ['armsvc', '1772'],
 ['audiodg', '4160'],
 ['AutoHotkeyU64', '472'],
 ['chrome', '6276'],
 ...

这篇关于配置IPython以使用Powershell而不是cmd的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆