【问题标题】:Shell Script with sqlplus and special characters on password带有 sqlplus 和密码特殊字符的 Shell 脚本
【发布时间】:2018-07-07 14:20:30
【问题描述】:

我有一个混合了 Linux / Unix shell 脚本和 sqlplus (Oracle) 的问题,这让我发疯了。 :-)

sqlplus 使用如下语法:

./sqlplus johnF/mypassword@127.0.0.1:1521/SID

而且效果很好。但是我的密码并不像“mypassword”那样简单,它使用“!”和“@”,有时甚至是“\”。对于这个例子,假设我的密码是 !p@ssword

如果我在 sqlplus 中使用以下语法,它可以工作:

./sqlplus johnF/'"!p@ssword"'@127.0.0.1:1521/SID

那太好了。但是我想在一个 shell 脚本中使用它来调用 sqlplus 并从文件中获取许多参数(用户名、密码、SID 和 SQL QUERY),例如让我使用简化的代码。

#!/bin/bash

while IFS=: read -r line
do

        echo "./sqlplus johnF/$line@127.0.0.1:1521/SID" 
        echo -e 'select 1 from dual;\nexit;' |  ./sqlplus johnF/$line@127.0.0.1:1521/SID

done < $1

我尝试了多种方式来修复它,包括:

echo -e 'select 1 from dual;\nexit;' |  ./sqlplus johnF/'"$line"'@127.0.0.1:1521/SID
echo -e 'select 1 from dual;\nexit;' |  ./sqlplus johnF/'\"$line\"'@127.0.0.1:1521/SID
echo -e 'select 1 from dual;\nexit;' |  ./sqlplus johnF/\'\"$line\"\'@127.0.0.1:1521/SID

还有很多其他的都失败了,在少数情况下,第一个 echo 打印输出完全符合它应该传递给 sqlplus,但它永远不会工作,返回登录被拒绝(密码错误)或连接问题(可能是 @ 被截获作为错误的目标)。

如何解决这个难题?

谢谢。

【问题讨论】:

  • 可能是this?或者也许使用heredoc?
  • 你可以使用sqlplus /nolog,然后在sqlplus 脚本中使用connect 语句。这应该会消除一些使问题复杂化的 shell 交互。
  • 你能分享你的alter user johnF identified by ???声明吗?
  • 有许多与数据库密码相关的特殊字符相关的 Oracle MOS 文章,例如 support.oracle.com/MMOS/faces/ui/km/…。有转义和使用引号的指导。
  • 谢谢大家,我的密码已正确更改。而且我知道shell转义的基本知识,但是我无法应用它来在shellscript中发送特殊密码,其中中间的数据是一个变量。我相信我的脚本重现了这个问题。有什么解决办法吗?谢谢。

标签: linux bash oracle shell sqlplus


【解决方案1】:

配置配置文件sqlnet.ora 以便于连接。

NAMES.DIRECTORY_PATH= (TNSNAMES,ezconnect)

将密码@T!ger 更改为用户“Scott”。

oracle@esmd:~>
oracle@esmd:~> sqlplus / as sysdba

SQL*Plus: Release 11.2.0.3.0 Production on Mon Jan 29 11:05:04 2018

Copyright (c) 1982, 2011, Oracle.  All rights reserved.


Connected to:
Oracle Database 11g Release 11.2.0.3.0 - 64bit Production

SQL> alter user "Scott" identified by "@T!ger";

User altered.

示例 1 脚本为 test_echo.sh

    #!/bin/sh

    username=\"Scott\"
    password=\"@T!ger\"
    ezconnect=10.89.251.205:1521/esmd

    echo username:  $username
    echo password:  $password
    echo ezconnect  $ezconnect

 echo -e 'show user \n  select 1 from dual;\nexit;' |  sqlplus  $username/$password@$ezconnect

oracle@esmd:~> ./test_echo.sh
username: "Scott"
password: "@T!ger"
ezconnect 10.89.251.205:1521/esmd

SQL*Plus: Release 11.2.0.3.0 Production on Mon Jan 29 11:02:52 2018

Copyright (c) 1982, 2011, Oracle.  All rights reserved.


Connected to:
Oracle Database 11g Release 11.2.0.3.0 - 64bit Production

SQL> USER is "Scott"
SQL>
         1
----------
         1

SQL> Disconnected from Oracle Database 11g Release 11.2.0.3.0 - 64bit Production

示例 2 以静默模式 sqlplus 运行脚本 test_echo.sh

#!/bin/sh

username=\"Scott\"
password=\"@T!ger\"
ezconnect=10.89.251.205:1521/esmd

echo username:  $username
echo password:  $password
echo ezconnect  $ezconnect
echo -e 'show user \n  select 1 from dual;\nexit;' |  sqlplus -s  $username/$password@$ezconnect

oracle@esmd:~> oracle@esmd:~> ./test_echo.sh
username: "Scott"
password: "@T!ger"
ezconnect 10.89.251.205:1521/esmd
USER is "Scott"

         1
----------
         1

示例 3 一点点另一种语法

#!/bin/sh

username=\"Scott\"
password=\"@T!ger\"
ezconnect=10.89.251.205:1521/esmd


echo username:  $username
echo password:  $password
echo ezconnect: $ezconnect

testoutput=$(sqlplus -s $username/$password@$ezconnect  << EOF
set pagesize 0 feedback off verify off heading off echo off;
show user
SELECT to_char(sysdate,'DD-MM-YYYY HH24:MI')||' Test passed' from dual
exit;
EOF
)

echo $testoutput

oracle@esmd:~> ./test_Upper_case.sh
username: "Scott"
password: "@T!ger"
ezconnect: 10.89.251.205:1521/esmd
USER is "Scott" 29-01-2018 11:55 Test passed

【讨论】:

    【解决方案2】:

    我假设您发布此文件是为了更改您的用户密码:

    alter user johnF identified by "!p@ssword";  
    

    因为

    alter user johnF identified by !p@ssword;  
    

    不符合oracle密码定义规则。

    然后在你的文件中编写这样一个脚本来连接你的架构就足够了:

    #!/bin/bash
    # cnn.sh
    line '"!p@ssword"'
    echo line
    sqlplus johnF/$line@127.0.0.1:1521/yourSID
    

    并从提示符中调用:

    $ . cnn.sh
    

    【讨论】:

      【解决方案3】:

      我在这里也遇到了同样的问题(这真的让我抓狂),这就是我的答案。

      Oracle 中允许的所有特殊字符都可以在此页面上找到: https://docs.oracle.com/cd/E11223_01/doc.910/e11197/app_special_char.htm#MCMAD416

      1. 如果您的 Oracle 密码包含上页中除单引号外的任何特殊字符。 #o@%+!$(){}[]/^?:`~ 例如。

      你可以这样使用它:

      sh test.sh oracle_user '"#o@%+!$(){}[]/\^?:`~"' ip port service_name
      
      1. 如果您的 Oracle 密码包含单引号。例如#o@%+!$(){}[]/^?:`~'。

      你可以这样使用它:

      sh test.sh oracle_user '"#o@%+!$(){}[]/\^?:`~'"'"'"' ip port service_name
      

      请注意,单引号'应替换为'""'。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-05
        • 2021-10-12
        • 2014-03-03
        • 1970-01-01
        • 2019-03-09
        • 1970-01-01
        相关资源
        最近更新 更多