在 MSWindows 上通过 SQLPLUS.exe HOST 命令调用 Shell

问题描述 投票:0回答:2

当用户提供 HOST 命令时,SQLPLUS 如何知道要调用哪个程序(在 MS Windows 上)?

(我希望用更严格的东西替换 cmd.exe,但不想破坏现有的 MSWindows 安装)

oracle cmd
2个回答
1
投票

识别 SQL*Plus 的 Shell

为了识别 SQL*Plus 在调用

HOST
命令时将使用的 shell,它指出要设置环境变量
SHELL
。这是 12c 文档

我的回答将集中于将 shell 更改为 powershell。

在带有 Powershell 5.1 的 Windows 7 上,我可以调用此命令来为我的笔记本电脑系统地设置环境变量

SHELL

[Environment]::SetEnvironmentVariable("SHELL", "powershell.exe" , "Machine")

接下来,我启动 SQL*Plus 会话并调用主机命令

host %shell% get-host
。这是我执行此命令的情况。

SCOTT@db>host %shell% get-host                                                           


Name             : ConsoleHost                                                               
Version          : 5.1.14409.1012                                                            
InstanceId       : b2585ba7-ea5f-452f-ba4f-d3dfc3032890                                      
UI               : System.Management.Automation.Internal.Host.InternalHostUserInterface      
CurrentCulture   : en-US                                                                     
CurrentUICulture : en-US                                                                     
PrivateData      : Microsoft.PowerShell.ConsoleHost+ConsoleColorProxy                        
DebuggerEnabled  : True                                                                      
IsRunspacePushed : False                                                                     
Runspace         : System.Management.Automation.Runspaces.LocalRunspace                      

直觉上,人们会期望调用

host
,然后调用 shell 命令(例如,在我的例子中是 powershell 命令),但这失败了:

SCOTT@db>host get-host                                                                   
'get-host' is not recognized as an internal or external command,                             
operable program or batch file.                                                              

基于这些结果并消除设置

SHELL
环境变量的需要,这将类似于我的其他
host
调用:

SCOTT@db>host powershell get-host


Name             : ConsoleHost
Version          : 5.1.14409.1012
InstanceId       : 305716aa-30dc-4ef8-9184-0cfce94254e5
UI               : System.Management.Automation.Internal.Host.InternalHostUserInterface
CurrentCulture   : en-US
CurrentUICulture : en-US
PrivateData      : Microsoft.PowerShell.ConsoleHost+ConsoleColorProxy
DebuggerEnabled  : True
IsRunspacePushed : False
Runspace         : System.Management.Automation.Runspaces.LocalRunspace

总结

也许将环境变量

SHELL
标识为非默认 shell 可在某些非 Windows 7 操作系统上运行,这种基于文档的设置并没有产生任何影响。

除了 SQL*Plus 设置和更改环境变量之外,如果您正在考虑更改 Windows 上的默认 shell,我会看到以下选项:

-更改组策略(例如,请参阅此链接

-根据 Microsoft Developer Network 的指示修改适当的注册表项。此链接上有许多重要说明,您需要确保这些说明与您正在使用的 Windows 版本相对应。


0
投票

我确认了帕特里克·培根的答案提供的结果,但我不同意底层的解释,并且在我的特定用例中,它不起作用。

我将从演示开始。

打开 PowerShell,然后

Push-Location
进入 UNC 路径。如果您从此处运行
cmd
,您应该会收到一条错误消息,指出您无法使用该工作目录,即使您尝试在调用中直接从
cmd
跳回到
powershell
也是如此。 (我已经自定义了
%PROMPT%
变量,因此您的结果可能会略有不同。)

PS Microsoft.PowerShell.Core\FileSystem::\\myserver.example.com\d$\KD> cmd
'\\myserver.example.com\d$\KD'
CMD.EXE was started with the above path as the current directory.
UNC paths are not supported.  Defaulting to Windows directory.
Microsoft Windows [Version 10.0.19045.4170]
(c) Microsoft Corporation. All rights reserved.

2024-04-11 12:30:22.22
Microsoft Windows [Version 10.0.19045.4170]
C:\Windows
>exit
PS Microsoft.PowerShell.Core\FileSystem::\\myserver.example.com\d$\KD> cmd /c powershell
'\\myserver.example.com\d$\KD'
CMD.EXE was started with the above path as the current directory.
UNC paths are not supported.  Defaulting to Windows directory.
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

Try the new cross-platform PowerShell https://aka.ms/pscore6

PS C:\Windows> exit
PS Microsoft.PowerShell.Core\FileSystem::\\myserver.example.com\d$\KD>

在 PowerShell 中,设置环境变量:

$ENV:MYSHELL='powershell'

从 PowerShell 运行

sqlplus /nolog
。让我们尝试以两种方式调用 powershell,既使用环境变量,又直接使用可执行文件的硬编码名称。

SQL> host powershell Get-Location

Path
----
Microsoft.PowerShell.Core\FileSystem::\\myserver.example.com\d$\KD



SQL> host %MYSHELL% Get-Location
'\\myserver.example.com\d$\KD'
CMD.EXE was started with the above path as the current directory.
UNC paths are not supported.  Defaulting to Windows directory.

Path
----
C:\Windows



SQL>

我们来说一下为什么我认为这两个结果不同。

%MYSHELL%
的情况下,因为 PowerShell 和 SQL*Plus 都不理解
%VARIABLE%
语法,所以在我看来 SQL*Plus 将命令发送到
cmd
进行解释,并且
cmd
正在解析
 %MYSHELL%
至“
powershell
”。由于错误消息,我们知道我们降落在
cmd

powershell
的情况下,因为
Get-Location
命令成功显示了推送的路径,我们知道它没有通过 cmd,所以这告诉我它正在使用指定的参数启动自己的子进程。

因此,它根本不调用特定的 shell 解释器。它生成自己的子进程,并在其内部逻辑认为合适时使用一些逻辑将某些事情交给

cmd

将隐式启动

cmd
的其他命令包括
echo
copy

我来到这里是因为我从 UNC 路径启动 PowerShell,并发现我的

copy
命令在运行时为我的脚本创建带时间戳的副本失败,并出现上述路径错误。我的解决方案是调用 powershell 来进行复制
host powershell Copy-Item
.

© www.soinside.com 2019 - 2024. All rights reserved.