是否有一种方法可以从父节点js脚本中调用派生子进程中的函数,即powershell脚本?
节点脚本:
const cp = require("child_process");
const psData = cp.spawn
("powershell -executionpolicy bypass ./powershell-script.ps1", [], {
shell: "powershell.exe",
});
powershell脚本:
function psDoSomething{
# do something
}
Node没有内置的方式来调用子进程中的特定函数。如果有帮助的话,您可以将参数传递给PS脚本,或者您可以生成/执行另一个PS脚本,但是Node不知道或不关心Powershell(或Python、Shell或生成/执行脚本中的任何其他语言)。如果你需要这个功能,你可以在NPM上尝试一个与powershell相关的包。
编辑:OP在评论中建议使用stdin.write
对子进程,并在子进程中收听STDIN,这是一个有趣的想法。我不使用Powershell,但下面是使用Bash的工作方式:
const bashSession = require('child_process').spawn('./foo.sh')
bashSession.stdin.setEncoding('utf-8')
bashSession.stdout.pipe(process.stdout)
bashSession.stdin.write('someFuncn')
bashSession.stdin.end()
#!/bin/bash
doThing() {
echo We made it here
}
while read line; do
if [[ $line == someFunc ]]; then
doThing
else
echo "$line"
fi
done < "${1:-/dev/stdin}"
让子进程监听stdin上的所有内容可能会产生问题,但同样的概念也可以用于指定文件或TCP套接字。
如果你想做的是一个一次性调用到你的PowerShell脚本中定义的函数,应该这样做:
let child = require('child_process').spawn(
'powershell',
[
'-noprofile', '-executionpolicy', 'bypass', '-c',
'. ./powershell-script.ps1; psDoSomething'
],
// In this simple example, pass the child process' output
// streams directly through to this process' output streams.
{ stdio: 'inherit' }
)
上面使用
powershell.exe
, Windows PowerShell命令行,与它的-c
/-Command
参数来处理一个给定的PowerShell代码片段。由于要调用的函数是在
./powershell-script.ps1
脚本中定义的,因此该脚本必须是点源的,以便将函数定义加载到调用者的作用域中。之后可以调用函数
如果您希望生成一个PowerShell子进程,您可以根据需要通过stdin迭代地提供命令以供稍后执行-换句话说:创建一个可编程控制的 REPL-你需要一个解决方案,其基本原理在Zac Anger的回答中概述,基于生成的PowerShell子进程与-c -
(-Command -
),即powershell.exe -noprofile -executionpolicy bypass -c -
- 警告:发送跨越多行的命令必须以两个换行符结束;有关详细信息,请参阅GitHub issue #3223。
let child = require('child_process').spawn(
// Start PowerShell in REPL mode, with -c - (-Command -)
'powershell',
[
'-noprofile', '-executionpolicy', 'bypass', '-c',
'-' // Start PowerShell as a REPL
]
)
// Connect the child process' output streams to the calling process',
// so they are *passed through*.
// Note: Using { stdio: 'inherit' } in the .spawn() call instead
// would prevent using child.stdin.write() below.
child.stdout.pipe(process.stdout)
child.stderr.pipe(process.stderr)
// Dot-source the file that defines the function.
// Note the double n to ensure that PowerShell recognizes the end of the command.
child.stdin.write('. ./powershell-script.ps1nn')
// Now you can invoke it.
child.stdin.write('psDoSomethingnn')
// ... pass additional commands, as needed.
// End the session.
child.stdin.write('"Goödbyə!"nn')
child.stdin.end()
字符编码注意:
child.stdin.write()
默认发送utf -8编码的字符串(您可以使用child.stdin.setEncoding()
更改编码,如Zac的回答所示)。Windows上的PowerShell可以正确地解释utf -8编码字符串也使它本身输出UTF-8,当前控制台的代码页必须是
65001
在之前-运行chcp
来验证。如果不是:如果您的Node.js程序从
cmd.exe
会话运行,请先运行以下命令:chcp 65001
如果在PowerShell会话中运行,请先执行以下命令:
$OutputEncoding = [Console]::InputEncoding = [Console]::OutputEncoding = [Text.UTF8encoding]::new()
在Unix类平台上,PowerShell幸运地将默认为UTF-8。