当前位置: 首页 > 知识库问答 >
问题:

管道破裂?

施冠玉
2023-03-14

我有一个非常奇怪的问题,我希望你的眼睛能帮助解决它。

我定义了一个函数,它通过BASH连接到Oracle SQL数据库。连接后,我使用一个herdeoc传入一个简单的select语句,该语句查找最大订阅id并递增它,具体取决于函数被调用的次数。代码如下:

    #!/bin/bash
    PASS=0
    function NewUserSubID(){
    PASS=$(($PASS+1))
    sqlplus "${DB_USER}"/"${DB_PASS}" <<EOF
    set echo on timing on lines 200 pages 100
    select max(SUBSCRIPTION_ID)+${PASS} from ${DB_ENV}.USER_DATA;
    EOF
    }

在命令行调用函数时,上述代码非常有效:

[root@localhost]> NewUserSubID
SQL*Plus: Release 11.2 Production
Copyright (c) 1982, 2013, Oracle.  All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2

SQL> SQL> 
MAX(SUBSCRIPTION_ID)+1
-------------------------------------
                                 1082
Elapsed: 00:00:00.00
SQL> Disconnected from Oracle Database 11g Enterprise Edition Release 11.2


[root@localhost]> NewUserSubID
SQL*Plus: Release 11.2 Production
Copyright (c) 1982, 2013, Oracle.  All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2

SQL> SQL> 
MAX(SUBSCRIPTION_ID)+2
-------------------------------------
                                 1083
Elapsed: 00:00:00.00
SQL> Disconnected from Oracle Database 11g Enterprise Edition Release 11.2


[root@localhost]> NewUserSubID
SQL*Plus: Release 11.2 Production
Copyright (c) 1982, 2013, Oracle.  All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2

SQL> SQL> 
MAX(SUBSCRIPTION_ID)+3
-------------------------------------
                                 1084
Elapsed: 00:00:00.00
SQL> Disconnected from Oracle Database 11g Enterprise Edition Release 11.2


[root@localhost]> NewUserSubID
SQL*Plus: Release 11.2 Production
Copyright (c) 1982, 2013, Oracle.  All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2

SQL> SQL> 
MAX(SUBSCRIPTION_ID)+4
-------------------------------------
                                 1085
Elapsed: 00:00:00.00
SQL> Disconnected from Oracle Database 11g Enterprise Edition Release 11.2

但是,当函数通过管道传输到AWK语句时,函数不再抖动,这毫无意义!请参阅下面的输出:

[root@localhost] > NewUserSubID | awk 'NR==9{print $1}'
1086
[root@localhost] > NewUserSubID | awk 'NR==9{print $1}'
1086
[root@localhost] > NewUserSubID | awk 'NR==9{print $1}'
1086
[root@localhost] > NewUserSubID | awk 'NR==9{print $1}'
1086
[root@localhost] > NewUserSubID | awk 'NR==9{print $1}'
1086

我不明白。哈哈,我真的希望我只是忽视了一些简单的东西,但我已经没有想法了。任何帮助都会很棒!

共有2个答案

白星海
2023-03-14

当您在不管道化结果的情况下运行函数时,它会在当前shell中运行。但是,当您运行管道时,管道中的每个命令都在自己的子shell中运行。除其他外,这意味着这些命令不能直接影响启动管道的shell环境。PASS变量在每个子shell中递增,但这种变化不会反映在父shell中,因此每个子shell都会看到该变量的相同初始值。

您可以在同一个shell中执行所有操作,也可以将PASS编号作为函数参数传递,并在外部管理增量。例如,

#!/bin/bash

PASS=0

NewUserSubID() {
sqlplus "${DB_USER}"/"${DB_PASS}" <<EOF
html" target="_blank">set echo on timing on lines 200 pages 100
select max(SUBSCRIPTION_ID)+${1} from ${DB_ENV}.USER_DATA;
EOF
}

# Use this instead of calling NewUserSubID directly:
NewUserSubID_Print() {
NewUserSubID $PASS | awk 'NR==9{print $1}'
PASS=$(($PASS+1))
}

但是,请注意不要试图捕获NewUserSubID\u Print()的输出,因为这将导致它在子shell中运行。如果要捕获输出,请让NewUserSubID\u Print()自己执行,并将其存储在shell变量中,以便调用方检索。

魏波娃
2023-03-14

问题是此处的命令中使用了管道:

NewUserSubID | awk 'NR==9{print $1}'

由于管道创建子shell,所以子shell中任何变量中所做的更改都不会反映在父shell中。

您可以在此处使用进程替换来避免子shell:

$> NewUserSubID> >(awk 'NR==9{print $1}')
1086

$> NewUserSubID> >(awk 'NR==9{print $1}')
1087

$> NewUserSubID> >(awk 'NR==9{print $1}')
1088
 类似资料:
  • 我正在对一个由zuul代理服务支持的简单Spring云应用程序进行一些压力测试。由于Zuul和服务之间的旧连接,我们偶尔会出现管道异常。我使用不同的配置选项配置Zuul,但没有成功: 例外情况如下: 通用域名格式。netflix。祖尔。例外ZuulException:组织转发错误。springframework。云netflix。祖尔。过滤器。路线RibbonRoutingFilter。转发(Ri

  • 我们将我们的集群迁移到Cassandra 1.2(从1.1.7),并尝试在迁移后运行修复(我们按照建议定期运行它们)。 由于SSTable版本不同,修复失败,因此我们使用和并重试。 但是,修复失败了,但有这个例外: 我们还注意到,在死亡之前,< code>nodetool netstats显示了奇怪的统计数据(表传输为756845%...). 编辑 这似乎是压缩SSTables传输的问题,我将尝试

  • 我正在实现与Android应用程序通信的服务器端应用程序。Android应用程序在最初与C服务器通信之前就已经实现了。现在我想用java代码替换C服务器。Android应用程序与服务器进行通信,通过读卡器中的卡对此人进行身份验证。 身份验证协议包含应用程序和服务器之间要成功完成的几个通信步骤。 应用程序和服务器之间的消息格式如下: 首先,应用程序发送一个类型1的请求来建立与读卡器中sim卡的连接。

  • 我使用ApacheCommons http客户端调用url,使用post方法发布参数,它很少抛出以下错误。 有人能建议是什么导致了这个异常以及如何调试它吗?

  • 问题内容: 目前,我正在使用内置于python的应用程序。当我在个人计算机上运行它时,它不会出现问题。 但是,当我将其移至生产服务器时。它不断向我显示以下错误: 我进行了一些研究,得出的原因是,当服务器仍在忙于发送数据时,最终用户浏览器会停止连接。 我想知道为什么会发生这种情况,以及根本原因是什么导致它无法在生产服务器上正常运行,而我的计算机却可以正常运行。任何建议表示赞赏 问题答案: 您的服务器

  • 我正在处理一个巨大的xml文档(包含大约一百万个条目),然后使用rabbitmq将一个格式化版本导入数据库。每次发布大约200000个条目后,我都会收到一个断管错误,rabbitmq无法从中恢复。 通知错误:f写():发送2651字节失败,errno=11资源暂时不可用在[/var/www/ribbon/app/控制台/命令/lib/php_amqplib/amqp.inc,第439行] 注意错误