简体   繁体   English

在powershell脚本中管理来自外部命令的输入

[英]Manage inputs from external command in a powershell script

First, I would like to apologize in case that the title is not descriptive enough, I'm having a hard time dealing with this problem. 首先,我想道歉,如果标题不够描述,我很难处理这个问题。 I'm trying to build an automation for a svn merge using a powershell script that will be executed for another process. 我正在尝试使用将为另一个进程执行的powershell脚本为svn合并构建自动化。 The function that I'm using looks like this: 我正在使用的功能如下所示:

function($target){
   svn merge $target
}

Now, my problem occurs when there are conflicts in the merge. 现在,当合并中存在冲突时,我的问题就出现了。 The default behavior of the command is request an input from the user and proceed accordingly. 该命令的默认行为是请求来自用户的输入并相应地继续。 I would like to automatize this process using predefined values (show the differences and then postpone the merge), but I haven't found a way to do it. 我想使用预定义的值自动化这个过程(显示差异,然后推迟合并),但我还没有找到办法。 In summary, the workflow that I am looking to accomplish is the following: 总之,我希望完成的工作流程如下:

  1. Detect whether the command execution requires any input to proceed 检测命令执行是否需要任何输入才能继续
  2. Provide a default inputs (in my particular case "df" and then "p") 提供默认输入(在我的特定情况下为“df”,然后是“p”)

Is there any way to do this in powershell? 有什么方法可以在powershell中做到这一点? Thank you so much in advance for any help/clue that you can provide me. 非常感谢您提供给我的任何帮助/线索。

Edit: 编辑:

To clarify my question: I would like to automatically provide a value when a command executed within a powershell script require it, like in the following example: 澄清我的问题:我想在powershell脚本中执行的命令需要时自动提供一个值,如下例所示:

Requesting user input 请求用户输入

Edit 2: 编辑2:

Here is a test using the snippet provided by @mklement0. 这是使用@ mklement0提供的代码段进行的测试。 Unfortunately, It didn't work as expected, but I thought it was wort to add this edition to clarify the question per complete 不幸的是,它没有按预期工作,但我认为添加此版本是为了澄清每个完整的问题

Expected behavior: 预期行为: 预期的行为

Actual result: 实际结果: 实际结果

You can store the SVN command line output into a variable and parse through that and branch as you desire. 您可以将SVN命令行输出存储到变量中,并根据需要对其进行解析和分支。 Each line of output is stored into a new enumerator (cli output stored in PS variables is in array format) 每行输出都存储到一个新的枚举器中(存储在PS变量中的cli输出是数组格式)

$var = & svn merge $target
$var

Note : 注意

  • This answer does not solve the OP's problem, because the specific target utility, svn , apparently suppresses prompts when the process' stdin input isn't coming from a terminal (console). 这个答案并没有解决OP的问题,因为当进程的stdin输入不是来自终端 (控制台)时,特定的目标实用程序svn显然会抑制提示

  • For utilities that do still prompt, however, the solution below should work, within the constraints stated. 但是,对于仍然提示的实用程序,下面的解决方案应该在规定的约束条件下工作。

  • Generally, before attempting to simulate user input, it's worth investigating whether the target utility offers programmatic control over the behavior, via its command-line options , which is both simpler and more robust. 通常,在尝试模拟用户输入之前,值得研究目标实用程序是否通过其命令行选项提供对行为的编程控制,这种选项既简单又强大。


While it would be far from trivial to detect whether a given external command is prompting for user input: 虽然检测给定的外部命令是否提示输入用户输入是微不足道的:

  • you can blindly send the presumptive responses, 你可以盲目地发送推定的答复,
  • which assumes that no situational variations are needed (except if a particular calls happens not to prompt at all, in which case the input is ignored). 假设不需要任何情境变化(除非特定的调用根本不发生提示,在这种情况下输入被忽略)。

Let's assume the following batch file, foo.cmd , which puts up 2 prompts and echoes the input: 让我们假设下面的批处理文件foo.cmd ,它提出2个提示并回显输入:

@echo off
echo begin
set /p "input1=prompt 1: "
echo [%input1%]
set /p "input2=prompt 2: "
echo [%input2%]
echo end

Now let's send responses one and two to that batch file: 现在让我们将响应onetwo发送到该批处理文件:

C: PS> Set-Content tmp.txt -Value 'one', 'two'; ./foo.cmd '<' tmp.txt; Remove-Item tmp.txt
begin
prompt 1: one
[one]
prompt 2: two
[two]
end

Note: 注意:

  • For reasons unknown to me, the use of an intermediate file is necessary for this approach to work on Windows - 'one', 'two' | ./foo.cmd 由于我不知道的原因,这种方法在Windows上工作需要使用中间文件 - 'one', 'two' | ./foo.cmd 'one', 'two' | ./foo.cmd does not work. 'one', 'two' | ./foo.cmd 不起作用

    • Note how the < must be represented as '<' to ensure that it is passed through to cmd.exe and not interpreted by PowerShell up front (where < isn't supported). 请注意<必须表示为'<'以确保它是如何传递给cmd.exe而不是由PowerShell预先解释(其中<不支持)。
  • By contrast, 'one', 'two' | ./foo 相比之下, 'one', 'two' | ./foo 'one', 'two' | ./foo does work on Unix platforms (PowerShell Core). 'one', 'two' | ./foo Unix平台上(PowerShell核心)工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM