我正在争论我是否应该学习PowerShell,还是坚持使用Cygwin/Perl脚本/Unix shell脚本等等。

PowerShell的好处是,没有Cygwin的队友可以更容易地使用脚本;然而,我不知道我是否真的会写那么多通用脚本,或者人们是否会使用它们。

Unix脚本功能如此强大,PowerShell是否足以让我们切换到它呢?

以下是我在PowerShell中寻找的一些具体内容(或等效内容):

grep 排序 uniq Perl (PowerShell与Perl的能力有多接近?) AWK sed File(提供文件信息的命令) 等。


当前回答

我发现PowerShell编程不值得付出努力。

我有几年在Unix下编写shell脚本的经验,但是我发现用PowerShell做任何事情都非常困难。

似乎许多函数都需要您查询Windows管理界面并发出类似sql的命令来获得所需的信息。

例如,我想编写一个脚本来从目录树中删除具有特定后缀的所有文件。在Unix下,这将是一个简单的…

find . -name \*.xyz -exec rm {} \;

在几个小时的脚本之后。FileSystemObject和WScript。Shell并发出“SELECT * FROM Win32_ShortcutFile WHERE Drive = '”& Drive & " and Path = '" & searchFolder & "'”,我最终放弃了,并解决了Windows资源管理器的搜索命令,只是手动执行。可能有一些方法可以做到我想要的,但我没有看到任何明显的东西,MSDN网站上的所有示例都是如此微不足道,以至于毫无价值。

EDIT嘿,当然,当我写这篇文章的时候,我又戳了一下,发现了我遗漏的东西:remove-item命令的-递归选项是错误的(如果你使用get-help remove-item -detailed就会显示出来)。

我一直在尝试“remove-item -filter '* .xyz' -recurse”,但它不起作用,所以我放弃了它。

事实证明你需要使用get-childitem -filter '*。Xyz ' -递归| remove-item

其他回答

PowerShell中的cmdlet非常好,工作可靠。因为我是一名Java/ c#开发人员,所以它们的面向对象性非常吸引我,但这并不是一个完整的集合。由于它是面向对象的,因此它错过了POSIX工具集(例如awk和sed)的许多文本流成熟度。

The best answer I've found to the dilemma of loving OO techniques and loving the maturity in the POSIX tools is to use both! One great aspect of PowerShell is that it does an excellent job piping objects to standard streams. PowerShell by default uses an object pipeline to transport its objects around. These aren't the standard streams (standard out, standard error, and standard in). When PowerShell needs to pass output to a standard process that doesn't have an object pipeline, it first converts the objects to a text stream. Since it does this so well, PowerShell makes an excellent place to host POSIX tools!

最好的POSIX工具集是GnuWin32。它确实需要超过5秒钟的时间来安装,但这是值得的,据我所知,它不会修改你的系统(注册表,c:\windows\*文件夹等),除了将文件复制到你指定的目录。这是非常好的,因为如果您将工具放在共享目录中,许多人可以同时访问它们。

GnuWin32安装说明

下载并执行exe(它来自SourceForge网站)指向一个合适的目录(我将使用C:\bin)。它会在那里创建一个GetGnuWin32目录,你将在其中运行download.bat,然后是install.bat(不带参数),之后会有一个C:\bin\GetGnuWin32\gnuwin32\bin目录,这是Windows机器上曾经存在过的最有用的文件夹。将该目录添加到路径中,就可以开始了。

TL;DR——我不讨厌Windows或PowerShell。我在Windows或PowerShell上什么都做不了。


我个人仍然觉得PowerShell充其量只能说是平淡无奇。

tab completion of directory paths do not compound, requiring the user to enter a path separator after every name completion. I still feel like Windows doesn't even have the concept of a path or of what a path is, with no accessible user home indicator ~/ short of some @environment://somejibberish/%user_home% NTFS is still a mess and seemingly always will be. Good luck navigating. cmd-esque interface, The dinosaur cmd.exe is still visible in PowerShell, Edit → Mark still being the only way to copy information, and copying only in the form of rectangular blocks of visible terminal space. and Edit → Mark still being the only way to paste strings into the terminal. Painting it blue doesn't make it any more attractive. I don't mind Microsoft developers having a taste in color though. Windows always opens at top left corner of screen. For somebody who uses vertical task bars this is incredibly annoying, especially considering that the Windows task bar will cover the only corner of the window that gives access to copy/paste functionality.

关于Windows包含的工具,我不能说太多。由于有一整套开源的、免费授权的CLI工具,而且PowerShell附带了这些工具,据我所知,没有一个是完全令人失望的。

PowerShell的wget的参数似乎与GNU的wget无法相比。谢谢,希望之光便携无用。 PowerShell POSIX与bash不兼容,特别是&&运算符没有被处理,使得最简单的条件命令也不能跟在后面。

我不了解人类;我试过了,真的;我仍然试着给它一个机会,希望下次我打开它的时候,它不会那么无用。我不能在PowerShell中做任何事情,我也几乎不能在真正的项目中将GNU工具引入Windows。

MySysGit为我提供了带有几个GNU工具的陈旧cmd.exe提示符,它仍然非常令人印象深刻,但最终路径补全工作了。Git命令将在Git Bash中运行。

Mintty for MySysGit为MySysGit的环境提供了Cygwin界面,使复制和粘贴一个东西(选择复制(鼠标),Shift+Ins粘贴,多么现代…)然而,像git push这样的东西在Mintty中被破坏了。

我并不是要抱怨,但我仍然看到Windows上命令行可用性的巨大问题,即使使用了Cygwin这样的工具。


注:仅仅因为在PowerShell中可以做一些事情,并不意味着它就可用。可用性比能力更重要,这也是我作为消费者在使用产品时所关注的问题。

当您将PowerShell与Cygwin/Perl/Shell组合进行比较时,请注意PowerShell仅表示该组合的“Shell”部分。

然而,您可以从PowerShell调用任何命令,就像从cmd.exe或Cygwin中调用一样。它没有重新实现指定的函数,当然也不能与Perl相比。

它“只是”一个外壳,但它使编程变得更容易,为。net世界提供了一个舒适的接口。

还要记住,PowerShell需要Windows XP、Windows Server 2003或更高版本,这可能会造成问题,具体取决于您的IT基础设施。

更新:

我不知道我的回答会引发什么样的哲学辩论。

我在这个问题的背景下发布了我的答案:将PowerShell与Cygwin、Perl和Bash进行比较。

PowerShell是一个shell,因为它在内置命令、命令行、用户函数和外部命令(.exe、.bat、.cmd)之间没有语法上的区别。只有在调用中添加名称空间或对象才能调用。net方法。

它的可编程性来源于。net框架,而不是任何特定于PowerShell“语言”的东西。

我想说,一旦Bugzilla或MediaWiki被实现为运行在web服务器上的PowerShell脚本,我相信PowerShell就是一种“脚本语言”。

在那之前,享受比较吧。

我直到最近才开始认真地接触PowerShell。尽管在过去的7年里,我一直在一个几乎完全基于Windows的环境中工作,但我有Unix背景,我发现自己一直在努力将我在Windows上的交互体验“Unix化”。至少可以说,这令人沮丧。

将PowerShell与Bash、tcsh或zsh这样的东西进行比较是公平的,因为grep、sed、awk、find等实用程序严格来说都不是shell的一部分;然而,它们将永远是任何Unix环境的一部分。也就是说,像Select-String这样的PowerShell命令具有与grep非常相似的功能,并且被捆绑为PowerShell的核心模块…所以界限可能有点模糊。

我认为最关键的是文化,而事实上,各自的工具集将体现各自的文化:

Unix is a file-based, (in general, non Unicode) text-based culture. Configuration files are almost exclusively text files. Windows, on the other hand has always been far more structured in respect of configuration formats--configurations are generally kept in proprietary databases (e.g., the Windows registry) which require specialised tools for their management. The Unix administrative (and, for many years, development) interface has traditionally been the command line and the virtual terminal. Windows started off as a GUI and administrative functions have only recently started moving away from being exclusively GUI-based. We can expect the Unix experience on the command line to be a richer, more mature one given the significant lead it has on PowerShell, and my experience matches this. On this, in my experience: The Unix administrative experience is geared towards making things easy to do in a minimal amount of key strokes; this is probably as a result of the historical situation of having to administer a server over a slow 9600 baud dial-up connection. Now PowerShell does have aliases which go a long way to getting around the rather verbose Verb-Noun standard, but getting to know those aliases is a bit of a pain (anyone know of something better than: alias | where {$_.ResolvedCommandName -eq "<command>"}?). An example of the rich way in which history can be manipulated: iptables commands are often long-winded and repeating them with slight differences would be a pain if it weren't for just one of many neat features of history manipulation built into Bash, so inserting an iptables rule like the following: iptables -I camera-1-internet -s 192.168.0.50 -m state --state NEW -j ACCEPT a second time for another camera ("camera-2"), is just a case of issuing: !!:s/-1-/-2-/:s/50/51 which means "perform the previous command, but substitute -1- with -2- and 50 with 51. The Unix experience is optimised for touch-typists; one can pretty much do everything without leaving the "home" position. For example, in Bash, using the Emacs key bindings (yes, Bash also supports vi bindings), cycling through the history is done using Ctrl-P and Ctrl-N whilst moving to the start and end of a line is done using Ctrl-A and Ctrl-E respectively ... and it definitely doesn't end there. Try even the simplest of navigation in the PowerShell console without moving from the home position and you're in trouble. Simple things like versatile paging (a la less) on Unix don't seem to be available out-of-the-box in PowerShell which is a little frustrating, and a rich editor experience doesn't exist either. Of course, one can always download third-party tools that will fill those gaps, but it sure would be nice if these things were just "there" like they are on pretty much any flavour of Unix. The Windows culture, at least in terms of system API's is largely driven by the supporting frameworks, viz., COM and .NET, both of-which are highly structured and object-based. On the other hand, access to Unix APIs has traditionally been through a file interface (/dev and /proc) or (non-object-oriented) C-style library calls. It's no surprise then that the scripting experiences match their respective OS paradigms. PowerShell is by nature structured (everything is an object) and Bash-and-friends file-based. The structured API which is at the disposal of a PowerShell programmer is vast (essentially matching the vastness of the existing set of standard COM and .NET interfaces).

简而言之,尽管PowerShell的脚本功能可以说比Bash更强大(特别是当您考虑到. net BCL的可用性时),但交互体验明显较弱,特别是如果您从完全由键盘驱动、基于控制台的角度(就像许多unix用户一样)进行交互时。

为什么不两者都用呢?在Cygwin中调用PowerShell脚本,就像其他解释性脚本(如Perl)一样。

为此,我编写了https://bitbucket.org/jbianchi/powershell,以便Bash包装器在Cygwin中调用powershell.exe。它可以用作PowerShell .exe .ps1脚本的第一行shebang(因为PowerShell也使用“#”作为注释)。参见https://bitbucket.org/jbianchi/powershell/wiki/Home获取示例