Windows 将IPython配置为使用powershell而不是cmd
搜索了这个,但似乎找不到任何已经问过的人,所以这里开始 我开始在Windows 7上切换到IPython作为我的go to shell,我想对它进行配置,以便bang magic(Windows 将IPython配置为使用powershell而不是cmd,windows,powershell,ipython,Windows,Powershell,Ipython,搜索了这个,但似乎找不到任何已经问过的人,所以这里开始 我开始在Windows 7上切换到IPython作为我的go to shell,我想对它进行配置,以便bang magic(!cmd)将命令传递给系统shell时使用PowerShell而不是cmd.exe,这样我就可以利用MS所做的增强,但不必将我的%COMSPEC%更改为PowerShell(我的公司仍然使用几种基于CMD的.bat实现自动化,我不想破坏它们) 我将在顶部发布我的问题,因为答案可能不需要以下任何信息: 我错过什么了吗?有
!cmd
)将命令传递给系统shell时使用PowerShell而不是cmd.exe,这样我就可以利用MS所做的增强,但不必将我的%COMSPEC%
更改为PowerShell(我的公司仍然使用几种基于CMD的.bat实现自动化,我不想破坏它们)
我将在顶部发布我的问题,因为答案可能不需要以下任何信息:
os.system()
将命令发送到shell,而不是subprocess.call()
。这使得事情变得有些复杂,因为os.system*只使用COMSPEC,而subprocess*可以指定要使用的可执行文件
我尝试加载PowerShell,设置$env:comspec
变量,然后从该shell中启动IPython,但即使comspec显示为set,即使在IPython中,看起来CMD仍在使用:
[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
看起来仍然在使用持久设置
我尝试了类似的方法,使用[Environment]::SetEnvironmentVariable(“ComSpec”,“powershell.exe”,“System.EnvironmentVariableTarget]::User”)
,以防我只更改一个用户范围的环境变量而不受影响,但这也不起作用(与上面的结果相同-os.getenv('ComSpec'))
显示powershell,但是!-ed命令被发送到CMD)
更改Machine-scope环境变量似乎可以满足我的要求,但由于前面提到的原因,这对我来说不是一个有效的解决方案
[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*中的设置测试了更多的解决方案。通过在“设置”>“启动”>“ComSpec”中将子进程的显式可执行文件和ComSpec环境变量设置为selected value*flags,并提供powershell.exe的路径,我可以在不更改全局变量的情况下完成此操作,但我不确定这是否会对使用ConEmu打开的CMD控制台产生负面影响,因为该设置是全局的(在ConEmu内)。这就是导致我提出上述问题2的原因,因为我不确定如何在PowerShell中设置进程/子本地、机器范围的环境变量(如果可能的话)
最后,我的理想目标是让IPython通过配置文件支持命令shell解释器的规范,但要做到这一点,os.system()
不能作为使用的工具。我打算在本地副本(a'la this)中修改一下,用subprocess.call()替换它进行测试,但是如果有人已经使用过它,或者如果当前模型比使用subprocess
有足够的优势,而我不知道,我会很高兴听到这个消息。看起来这项工作已经在非Windows系统()上进行了,但我对Python的这种规模还不够熟悉,因此我不能肯定,如果在条件的Windows端也使用了这种更改,那么其他任何东西都不会被破坏
脚注
啊!显然,必须有10+的声誉才能正确记录问题。以下是我不允许在上面发布的链接:
- 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/
这有点狡猾,但您可以使用调用预先制作的powershell脚本
os.system('powershell C:\file.ps1')
或者像这样的单个命令:
os.system(“powershell;gci |其中{$\.Fullname-包含一些东西”)
编辑:
我刚刚测试了这个,它似乎只需要打开一个powershell实例:
os.system(“powershell;gci;gc C:\windows\system32\drivers\etc\services;[system.net.dns]::gethostbyaddress('203.20.74.6')|更多”)
但我想如果你不得不在剧本中多次调用这种类型的东西,它可能会变得丑陋和缓慢 您可以使用IPython的脚本magics执行PowerShell命令
定义魔法
在中,修改ipython_config.py
以包括以下行:
c.ScriptMagics.script_magics = ['powershell']
c.ScriptMagics.script_paths = {
'powershell':'powershell.exe -noprofile -command -'}
-command-
告诉PowerShell将stdin文本作为命令执行。如果需要加载PS配置文件,可以省去-noprofile
,但速度会慢一些
然后,您可以使用%%powershell
作为一个应用程序
自定义魔法
为了使它更易于使用,我定义了自己的magic函数,用line和cell magics处理PowerShell命令。(请参阅:)将脚本放置在IPython配置文件的启动文件夹中,可以自动加载该脚本。(即~\.ipython\profile\u default\startup\05-powershell\u magic.py
)
用法示例
要使用%ps
行魔术并将输出返回到变量,请执行以下操作:
In [1]: ps_version = %ps $PSVersionTable.PSVersion.ToString()
In [2]: print(ps_version)
['2.0']
要使用%%ps
单元格魔术并输出到控制台:
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
Cell magics可以使用--out
将输出发送到变量:
最简单的方法是在Jupiter笔记本或python shell中导入操作系统并更新环境变量comspec
导入操作系统
os.environ['comspec']='powershell.exe'
os.getenv('comspec')
然后使用下面的命令
!gc log.txt | select -first 10 # head
!gc -TotalCount 10 log.txt # also head
!gc log.txt | select -last 10 # tail
!gc -Tail 10 log.txt # also tail (since PSv3), also much faster than above option
!gc log.txt | more # or less if you have it installed
!gc log.txt | %{ $_ -replace '\d+', '($0)' } # sed
还有莫
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
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'],
...
!gc log.txt | select -first 10 # head
!gc -TotalCount 10 log.txt # also head
!gc log.txt | select -last 10 # tail
!gc -Tail 10 log.txt # also tail (since PSv3), also much faster than above option
!gc log.txt | more # or less if you have it installed
!gc log.txt | %{ $_ -replace '\d+', '($0)' } # sed