运行 来自 Java 的 PowerShell 文件说该文件没有“.ps1”扩展名
Running a PowerShell file from Java says the file does not have a '.ps1' extension
我正在尝试弄清楚如何从 Java 中 运行 PowerShell 脚本。请记住,我是 Java 的新手,因此可能有更好的方法。
目前我在安装了 PowerShell 的 Fedora 25 工作站上。
如here所述,先安装 Fedora .NET Core 软件包:
sudo dnf config-manager --add-repo https://copr.fedorainfracloud.org/coprs/nmilosev/dotnet-sig/repo/fedora-25/nmilosev-dotnet-sig-fedora-25.repo
sudo dnf update
sudo dnf install dotnetcore
然后下载RPM for CentOS 7并安装。
sudo dnf install Downloads/powershell-6.0.0_beta.1-1.el7.centos.x86_64.rpm
powershell
然后我使用这个 中的代码到 运行 一个 "Hello world" ps1 文件:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class PowerShellCommand {
public static void main(String[] args) throws IOException {
String command = "powershell $PSVersionTable.PSVersion";
command = "powershell -ExecutionPolicy RemoteSigned -NoProfile -NonInteractive -File \"/home/b/Downloads/MyScript.ps1\"";
Process powerShellProcess = Runtime.getRuntime().exec(command);
powerShellProcess.getOutputStream().close();
String line;
System.out.println("Standard Output:");
BufferedReader stdout = new BufferedReader(new InputStreamReader(
powerShellProcess.getInputStream()));
while ((line = stdout.readLine()) != null) {
System.out.println(line);
}
stdout.close();
System.out.println("Standard Error:");
BufferedReader stderr = new BufferedReader(new InputStreamReader(
powerShellProcess.getErrorStream()));
while ((line = stderr.readLine()) != null) {
System.out.println(line);
}
stderr.close();
System.out.println("Done");
}
}
我在尝试 运行 .ps1 文件时遇到的错误是:
Processing -File '"/home/b/Downloads/MyScript.ps1"' failed because the
file does not have a '.ps1' extension. Specify a valid Windows
PowerShell script file name, and then try again.
在 Java 代码中尝试 运行 时,我确实得到了变量的正确输出:
String command = "powershell $PSVersionTable.PSVersion";
当 运行 在 Gnome 终端中从 bash shell 中执行以下操作时,这也可以正常工作,并且通过说 "Hello world" 可以正确执行脚本:
powershell -ExecutionPolicy RemoteSigned -NoProfile -NonInteractive -File "/home/b/Downloads/MyScript.ps1"
感谢您的帮助。
注意:
自问题发布后,PowerShell Core 可执行文件 的名称已从 powershell
更改为 pwsh
,这反映在下面的解决方案中。
问题中的特定脚本文件路径 - /home/b/Downloads/MyScript.ps1
- 不是严格要求quoting(包含在 "..."
中),但是 一个普遍可靠的解决方案 应该 使用 quoting - 这就是下面所展示的。
通过将命令构造为 单个字符串 , 嵌入的 "
实例将保留为literals,错误信息反映的是:
Processing -File '"/home/b/Downloads/MyScript.ps1"'
...
请注意 '...'
中引用的值如何包含 "..."
- 字面上包含 "
个字符的路径显然不存在 - 由于以 [=16 结尾=] - 没有 .ps1
扩展名。
什么single-command-string form of Runtime.exec()
does is to perform by-whitespace-only tokenizing of the string via StringTokenizer
。因此,生成的数组保留了嵌入的引号,并且也不会将带有嵌入空格的引用标记识别为单个标记。
你有两个选择来解决这个问题:
(a) 使用 -Command
和 &
而不是 -File
来调用脚本,在这种情况下PowerShell 使用 另一轮解析,因此嵌入的 "
实例被识别为具有句法功能。
String command = "pwsh -NoProfile -Command & \"/home/b/Downloads/MyScript.ps1\"";
(b) 最好,将命令行的token作为字符串传递array:
String[] command = new String[] { "pwsh", "-NoProfile", "-File", "/home/b/Downloads/MyScript.ps1" };
请注意,对于 (a),如果您在命令字符串中包含要传递给脚本的参数,这些参数也会由 PowerShell 解析,这意味着您可能也需要为它们嵌入引号。
注意如何使用 (b) 不需要嵌入引号 脚本路径参数,因为它被指定为它自己的数组元素。通过使用 PowerShell 的 -File
参数,所有传递的参数都被视为 文字 .
我正在尝试弄清楚如何从 Java 中 运行 PowerShell 脚本。请记住,我是 Java 的新手,因此可能有更好的方法。
目前我在安装了 PowerShell 的 Fedora 25 工作站上。
如here所述,先安装 Fedora .NET Core 软件包:
sudo dnf config-manager --add-repo https://copr.fedorainfracloud.org/coprs/nmilosev/dotnet-sig/repo/fedora-25/nmilosev-dotnet-sig-fedora-25.repo
sudo dnf update
sudo dnf install dotnetcore
然后下载RPM for CentOS 7并安装。
sudo dnf install Downloads/powershell-6.0.0_beta.1-1.el7.centos.x86_64.rpm
powershell
然后我使用这个
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class PowerShellCommand {
public static void main(String[] args) throws IOException {
String command = "powershell $PSVersionTable.PSVersion";
command = "powershell -ExecutionPolicy RemoteSigned -NoProfile -NonInteractive -File \"/home/b/Downloads/MyScript.ps1\"";
Process powerShellProcess = Runtime.getRuntime().exec(command);
powerShellProcess.getOutputStream().close();
String line;
System.out.println("Standard Output:");
BufferedReader stdout = new BufferedReader(new InputStreamReader(
powerShellProcess.getInputStream()));
while ((line = stdout.readLine()) != null) {
System.out.println(line);
}
stdout.close();
System.out.println("Standard Error:");
BufferedReader stderr = new BufferedReader(new InputStreamReader(
powerShellProcess.getErrorStream()));
while ((line = stderr.readLine()) != null) {
System.out.println(line);
}
stderr.close();
System.out.println("Done");
}
}
我在尝试 运行 .ps1 文件时遇到的错误是:
Processing -File '"/home/b/Downloads/MyScript.ps1"' failed because the file does not have a '.ps1' extension. Specify a valid Windows PowerShell script file name, and then try again.
在 Java 代码中尝试 运行 时,我确实得到了变量的正确输出:
String command = "powershell $PSVersionTable.PSVersion";
当 运行 在 Gnome 终端中从 bash shell 中执行以下操作时,这也可以正常工作,并且通过说 "Hello world" 可以正确执行脚本:
powershell -ExecutionPolicy RemoteSigned -NoProfile -NonInteractive -File "/home/b/Downloads/MyScript.ps1"
感谢您的帮助。
注意:
自问题发布后,PowerShell Core 可执行文件 的名称已从
powershell
更改为pwsh
,这反映在下面的解决方案中。问题中的特定脚本文件路径 -
/home/b/Downloads/MyScript.ps1
- 不是严格要求quoting(包含在"..."
中),但是 一个普遍可靠的解决方案 应该 使用 quoting - 这就是下面所展示的。
通过将命令构造为 单个字符串 , 嵌入的 "
实例将保留为literals,错误信息反映的是:
Processing -File
'"/home/b/Downloads/MyScript.ps1"'
...
请注意 '...'
中引用的值如何包含 "..."
- 字面上包含 "
个字符的路径显然不存在 - 由于以 [=16 结尾=] - 没有 .ps1
扩展名。
什么single-command-string form of Runtime.exec()
does is to perform by-whitespace-only tokenizing of the string via StringTokenizer
。因此,生成的数组保留了嵌入的引号,并且也不会将带有嵌入空格的引用标记识别为单个标记。
你有两个选择来解决这个问题:
(a) 使用
-Command
和&
而不是-File
来调用脚本,在这种情况下PowerShell 使用 另一轮解析,因此嵌入的"
实例被识别为具有句法功能。String command = "pwsh -NoProfile -Command & \"/home/b/Downloads/MyScript.ps1\"";
(b) 最好,将命令行的token作为字符串传递array:
String[] command = new String[] { "pwsh", "-NoProfile", "-File", "/home/b/Downloads/MyScript.ps1" };
请注意,对于 (a),如果您在命令字符串中包含要传递给脚本的参数,这些参数也会由 PowerShell 解析,这意味着您可能也需要为它们嵌入引号。
注意如何使用 (b) 不需要嵌入引号 脚本路径参数,因为它被指定为它自己的数组元素。通过使用 PowerShell 的 -File
参数,所有传递的参数都被视为 文字 .