【问题标题】:Escaping symbols in cron在 cron 中转义符号
【发布时间】:2011-11-16 01:40:52
【问题描述】:

我有以下脚本(它连接到 oracle 数据库,查找应用的 arclog 并将其删除):

ARCLOGS=$(/oracle/base11202/11202/bin/sqlplus -s /  as sysdba <<EOF
set head off
set verify off
set feedback off
select name from v$archived_log where applied = 'YES' and first_time > sysdate - 1 order by sequence#;
exit;
EOF)

echo "${ARCLOGS}" | while read arc
do
  if [[ -e $arc ]] 
  then
    rm -f $arc
  fi
done

当我自己启动它时它工作正常。但想法是从 cron 开始。 Cron 在尝试启动此脚本时出错:

Your "cron" job executed on test on Mon Nov 14 15:17:00 2011
if [ -e /arclogs/arcs.sh ]; then sh -x /arclogs/arcs.sh; fi 


produced the following output:

+ + /oracle/base11202/bin/sqlplus -s / as sysdba
+ 0<<
set head off
set verify off
set feedback off
select name from v$archived_log where applied = "YES" and first_time > sysdate - 1 order by sequence#;
exit;
ARCLOGS=select name from v$archived_log where applied = "YES" and first_time > sysdate - 1 order by sequence#
                                                *
ERROR at line 1:
ORA-00904: "YES": invalid identifier
+ read arc
+ echo select name from v$archived_log where applied = "YES" and first_time > sysdate - 1 order by sequence#
                                                *
ERROR at line 1:
ORA-00904: "YES": invalid identifier
+ [[ -e select name from v$archived_log where applied = "YES" and first_time > sysdate - 1 order by sequence# ]]
+ read arc
+ [[ -e * ]]
+ read arc
+ [[ -e ERROR at line 1: ]]
+ read arc
+ [[ -e ORA-00904: "YES": invalid identifier ]]
+ read arc

看起来像是转义符号的问题。但我不知道我必须逃避什么。

顺便说一句,当我将脚本分成两部分时,脚本可以与 cron 一起使用:

arcs.sh:

ARCLOGS=$(/oracle/base11202/bin/sqlplus -s /  as sysdba <<EOF
set head off
set verify off
set feedback off
select name from v$archived_log where applied = 'YES' and first_time > sysdate - 1 order by sequence#;
exit;
EOF)

echo "${ARCLOGS}" | while read arc
do
  if [[ -e $arc ]] 
  then
    rm -f $arc
  fi
done

和 arcs.sql:

connect / as sysdba
set head off
set verify off
set feedback off
select name from v$archived_log where applied = 'YES' and first_time > sysdate - 1 order by sequence#;
exit;

但我想把它合二为一。有人可以帮忙吗?

【问题讨论】:

  • 向我们展示您在 crontab 中放入的行。
  • 在cron输出的第二行if [ -e /arclogs/arcs.sh ]; then sh -x /arclogs/arcs.sh; fi
  • 尝试将&lt;&lt;EOF 更改为&lt;&lt;'EOF'。这应该可以防止 shell 解释此处文档中的任何内容。
  • 请参阅我的回答中的编辑 2。尝试将 'YES' 放在双引号内:“'YES'”。
  • &lt;&lt;EOF 更改为 &lt;&lt;'EOF' 没有帮助。

标签: oracle bash cron heredoc


【解决方案1】:

只是在黑暗中拍摄。尝试从您的 cron 行显式调用 /bin/bash。 Cron 默认使用 sh 执行。

【讨论】:

  • 你的意思是把if [ -e /arclogs/arcs.sh ]; then sh -x /arclogs/arcs.sh; fi改成if [ -e /arclogs/arcs.sh ]; then /bin/bash /arclogs/arcs.sh; fi
  • 我开始认为这就是答案 - 你的 /bin/sh 奇怪地解释了 $(...)。如果您将其更改为使用反引号,它会起作用吗?无论如何,我会完全取出变量,然后做sqlplus &lt;&lt;EOF | while read ...
  • @stee1rat 不,在实际的 cron 行上。有 * * * * * 部分作为时间规范。之后放“/bin/bash /arclogs/arcs.sh.”
  • 我应该先试试你的答案,因为它有帮助!感谢大家尝试提供帮助! :)
【解决方案2】:

尝试用反斜杠转义单引号:

select name from v$archived_log where applied = \'YES\' and first_time > sysdate - 1 order by sequence#;

引号显然被 shell 吃掉了,Oracle 正试图将裸字符串 YES 解释为标识符而不是字符串常量。

编辑:

cron 任务是在你的 ID 下运行的吗?

编辑 2:

试试这个:

select name from v$archived_log where applied = "'YES'" and first_time > sysdate - 1 order by sequence#;

【讨论】:

  • 不,问题仍然存在。除了它在错误消息中显示\'YES\'。顺便说一句,为什么它显示"YES" 而不是'YES' 而没有转义(我原来的帖子中的错误消息)?
  • 因为 Oracle 认为您已经向它传递了一个名为 YES 的标识符。 Oracle 将标识符放在双引号中,这在这里令人困惑。我已经有一段时间没有使用任何 *nix shell 了,所以我不记得你需要如何转义单引号,但我今天会考虑一下。
  • 不,错误信息来自shell; Oracle 的输出是一条从read 回显的错误消息。
  • Oracle 的输出是生成的错误消息,因为引号没有作为 SELECT 语句的一部分传递,并且值 YES 被传递给 Oracle,Oracle 将其解释为标识符,它不是,因此是 ORA-00904。
  • 不,它没有帮助..现在它说“'YES'”是无效的标识符..所以我认为除了额外的.sql文件之外没有解决方案。
猜你喜欢
  • 2013-05-13
  • 1970-01-01
  • 2010-11-11
  • 2018-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-06
相关资源
最近更新 更多