如何从字符串中执行任意本机命令?

Joh*_*man 195 powershell scripting

我可以通过以下方案表达我的需求:编写一个接受字符串的函数作为本机命令运行.

这并不是一个想法:如果你正在与公司其他地方的其他命令行实用程序连接,那么它将为你提供逐字运行的命令.因为您不控制命令,所以您需要接受任何有效的命令作为输入.这些是我无法轻易克服的主要问题:

  1. 该命令可能执行生活在其中包含空格的路径中的程序:

    $command = '"C:\Program Files\TheProg\Runit.exe" Hello';
    
    Run Code Online (Sandbox Code Playgroud)
  2. 该命令可能包含带空格的参数:

    $command = 'echo "hello world!"';
    
    Run Code Online (Sandbox Code Playgroud)
  3. 该命令可能包含单蜱和双蜱:

    $command = "echo `"it`'s`"";
    
    Run Code Online (Sandbox Code Playgroud)

没有干净的方法来完成这个?我只能设计出奢华和丑陋的变通方法,但对于脚本语言,我觉得这应该是简单的.

Joe*_*ant 299

Invoke-Expression,也有别名iex.以下内容适用于您的示例#2和#3:

iex $command
Run Code Online (Sandbox Code Playgroud)

某些字符串不会按原样运行,例如您的示例#1,因为exe是引号.这将按原样工作,因为字符串的内容正是您从Powershell命令提示符直接运行它的方式:

$command = 'C:\somepath\someexe.exe somearg'
iex $command
Run Code Online (Sandbox Code Playgroud)

但是,如果exe是引号,则需要帮助&它运行,如本例所示,从命令行运行:

>> &"C:\Program Files\Some Product\SomeExe.exe" "C:\some other path\file.ext"
Run Code Online (Sandbox Code Playgroud)

然后在脚本中:

$command = '"C:\Program Files\Some Product\SomeExe.exe" "C:\some other path\file.ext"'
iex "& $command"
Run Code Online (Sandbox Code Playgroud)

可能,您可以通过检测命令字符串的第一个字符是否可以处理几乎所有情况",就像在这个天真的实现中一样:

function myeval($command) {
    if ($command[0] -eq '"') { iex "& $command" }
    else { iex $command }
}
Run Code Online (Sandbox Code Playgroud)

但是您可能会发现其他一些必须以不同方式调用的情况.在这种情况下,您将需要使用try{}catch{}(可能是特定的异常类型/消息)或检查命令字符串.

如果你总是收到绝对路径而不是相对路径,那么在上面的2之外你不应该有很多特殊情况,如果有的话.

  • 您可能需要输入"&"或"." 在实际命令之前签名,如果它不是powershell-native,例如`Invoke-Expression'&$ command"` (3认同)
  • 别名很棒.请记住,如果您移动到另一台计算机或将该脚本发送给其他人,则可能无法设置别名.首选PowerShell函数的全名. (2认同)

Luk*_*ett 17

另请参阅此Microsoft Connect报告本质上,如何使用PowerShell运行shell命令很困难(哦,具有讽刺意味).

http://connect.microsoft.com/PowerShell/feedback/details/376207/

他们建议使用--%强制PowerShell停止尝试解释右侧文本的方法.

例如:

MSBuild /t:Publish --% /p:TargetDatabaseName="MyDatabase";TargetConnectionString="Data Source=.\;Integrated Security=True" /p:SqlPublishProfilePath="Deploy.publish.xml" Database.sqlproj
Run Code Online (Sandbox Code Playgroud)

  • 以上链接位于 archive.org 上:http://web.archive.org/web/20131122050220/http://connect.microsoft.com:80/PowerShell/feedback/details/376207 (4认同)
  • 啊,微软破坏了互联网,链接不再有效。 (2认同)
  • 我喜欢这篇文章。完全概括了“pwsh”为何“不是” shell。 (2认同)

js2*_*010 6

如果要使用调用运算符,参数可以是存储在变量中的数组:

$prog = 'c:\windows\system32\cmd.exe'
$myargs = '/c','dir','/x'
& $prog $myargs
Run Code Online (Sandbox Code Playgroud)

调用运算符也适用于 ApplicationInfo 对象。

$prog = get-command cmd
$myargs = -split '/c dir /x'
& $prog $myargs
Run Code Online (Sandbox Code Playgroud)