当$ORACLE_HOME路径中有空格时如何卸载Oracle DB Client?

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

我有很多 Windows 计算机,需要删除并重新安装 Oracle 数据库客户端。我遇到的问题是安装它们的人都使用

C:\Program Files\Oracle\Database Client\21.0.0
作为
$ORACLE_HOME
目录而不是默认的
C:\app
。 Oracle 的内置卸载程序无法处理包含空格的文件路径。

卸载一个简单的批处理文件,该文件调用几个 Perl 脚本,并以

$ORACLE_HOME
作为参数,所以我决定手动调用
bootstrap.pl
,这就是我得到的:

C:\>"C:\Program Files\Oracle\Database Client\21.0.0\perl\bin\perl.exe" "C:\Program Files\Oracle\Database Client\21.0.0\deinstall\bootstrap.pl" 1 ^"C:\Program Files\Oracle\Database Client\21.0.0^"

18 File(s) copied
Invalid number of parameters
Bootstrap Failed. at C:\Program Files\Oracle\Database Client\21.0.0\deinstall\bootstrap.pl line 148

*请注意,上面命令行中的脱字号 (^) 需要转义双引号。否则,你最终会以

C:\Program
作为参数。

以下是

bootstrap.pl
脚本中的相关代码行:

  my @sourceDirs = ($dest.$dirSep.'deinstall',$ORACLE_HOME.$dirSep.'oui',$ORACLE_HOME.$dirSep.'perl',$ORACLE_HOME.$dirSep.'jdk',$ORACLE_HOME.$dirSep.'oracle_common');
   if($giHomeCleanFound == 0)
   {
   
   if ( $^O eq "MSWin32" ) {
      system("xcopy /y/s/i/e/q $sourceDirs[0] $dest") == 0 or die "Bootstrap Failed.";
      print $ORACLE_HOME.$dirSep.'oui';   #<-- I added this statement to see what the sting looks like 
      system("xcopy /y/s/i/e/q $sourceDirs[1] $dest\\oui") == 0 or die "Bootstrap Failed.";   #<-- This is the line where it fails
      system("xcopy /y/s/i/e/q $sourceDirs[2] $dest\\perl") == 0 or die "Bootstrap Failed.";
      system("xcopy /y/s/i/e/q $sourceDirs[3] $dest\\jdk") == 0 or die "Bootstrap Failed."; 
      if ($nextGen eq "true") {
        system("xcopy /y/s/i/e/q $sourceDirs[4] $dest\\oracle_common") == 0 or die "Bootstrap Failed.";
      } 
   }

实际上,Perl 脚本只是将工作发送回命令行。这基本上是双引号没有正确转义的恶性循环。这只是 Perl 脚本之一的一个块,所以我确信这种代码无处不在。我真的不想为他们重写 Oracle 的脚本。我曾经尝试编写 Oracle 的手动删除指令脚本,但进展并不顺利。

有没有办法从命令行转义双引号,以便从 Perl 脚本传回命令行时可以正确转义双引号?

或者有没有更好的工具可以干净地删除客户端?

perl
1个回答
0
投票

如果您只是想卸载这些东西,那么修复 perl 可能不值得。您可以看到它正在尝试执行的操作,然后手动执行即可。然后你继续生活。有时,我还发现,当这是一件不需要未来关注的一次性事情时,将空间从路径中移出会更容易。

现在,谈谈一些有趣的观点。

我不玩Oracle,所以我只是回应总体想法。而且,如果 bootstrap.pl 是由 Oracle 提供的,也许您可以赢得 bug 赏金(如果他们甚至这样做的话)。

一般来说,不要从用户输入(或外部源)创建命令字符串,然后将大字符串交给

system
。有时我们会出于各种安全考虑而谈论这一点。例如,如果有人可以搞乱决定最终在
@sourcedirs
中的路径的各种输入,他们可能能够在该
system
中执行其他 DOS 命令。我在《掌握 Perl》的安全章节中介绍了这类内容,并且很多人在其他地方写过相关内容,所以我们就不再赘述了。 perlsec 也是一本好书。 作为奖励,如果您正在玩 Perl Bar 琐事,这里还有一些其他奇怪的事情。

    File::Spec::catfile
  • 可以在没有
    $dirsep
    的情况下创建路径。
    目录分隔符位于 perl 配置中。
  • $ perl -V:path_sep path_sep=';' $ perl -MConfig -le "print $Config{path_sep}" ;
我们需要更多地讨论路径中的空间。不知何故,路径中空格的想法还没有跟上编程实践的步伐。我们都知道在编写代码之前可能会有空格。

@ikegami 已经指出了

Win32::Shellquote

。我还有 Perl.com 文章“引用 Shell”: use Win32::ShellQuote qw(:all); system quote_system( qw(xcopy /y/s/i/e/q), $sourceDirs[0], $dest );

还有多种其他方法可以引用 Win32 shell 命令,具体取决于您想要执行的操作。

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