Bash linux 强制多个实例等待 运行 sqlplus 命令完成

Bash linux force multiple instances to wait for running sqlplus command to finish

我有一个 bash 脚本,可以同时允许多个 运行 实例。但是,有一个到 Oracle 数据库的 sqlplus 连接来检索值。如果多个 bash 脚本实例同时获取此值,它们可能会检索到相同的值,因为当第一个实例仍在处理时,第二个实例已经在验证 'old data'.

我只能想到两个选项,一个是用PIDFILE锁定函数。缺点是如果用户在删除 pid 文件之前中止操作,则会导致问题。另一个是基于声明用 ps -ef | grep 'scriptname' | wc -l 计数的最大进程来锁定整个脚本。但这会锁定整个脚本,而不仅仅是数据库部分。

那么还有其他选择吗?这个与数据库的 sqlplus 连接是否有可能以某种方式捕获,以便我可以在其中一个实例执行此函数时暂停多个 运行 实例?

您可以在 tmp 文件中使用唯一值(/tmp/pidfile 对于本例),并在脚本中止或完成时重置它。

更新:这看起来很可靠,请参阅底部的测试。

#!/bin/bash


bashpid="$$"                     # Records PID of script.  Unused so far
pidfile=/tmp/pidfile             # pidfile var
pidlimit=2                       # pidlimit

cleanup () {                     # cleanup operations
        exit
    }

pidreset () {                    # trap operations (if reqd)
        pkill -a -P "$bashpid"
        kill -9 0
    }

trap "pidreset" SIGINT           # trap (if reqd)


countpid () {                    # This is the true PID count, only called
                                 # Once allowed in the database block
                                 # This includes self instance

     ps aux | grep "$(basename [=10=])" | grep -v grep > $pidfile

}

countloop () {                   # This counts PID while waiting for a spot
                                 # (-1 decrement since self is included but 
                                 # not yet granted access to database block)
    echo "(( ("$(ps aux | grep "$(basename [=10=])" | grep -v grep | wc -l )") - 1))" | bc > $pidfile

}
databasecall () {                # The database script calls

    touch $pidfile
    pidcount="$(cat $pidfile | wc -l)"
    until [[ "$pidcount" -le "$pidlimit" ]]; do
        echo "too many processes"
        countloop 
        pidcount="$(cat $pidfile | wc -l)"
        sleep 5
    done

    #   ================  Start of Database access Code ================
    #   Go ahead and do database stuff
    #   Write this script into the pidfile incrementing its count also

    countpid 
    pidcount="$(cat $pidfile | wc -l)"
    echo "We're in"
    echo "Scriptcount: $pidcount (Including this one)"
    sleep 5
    cleanup
    # return / whatever
    #   ================  End of Database access Code ================

}



echo "Main script block"          # Main script outside of Database block
sleep .1


databasecall                      # Call database function


cleanup                           # Call to housekeeping

测试

它工作正常但稳定在 运行 比 pidlimit 多一个,虽然我不确定这是在哪里发生的或者它是否是我的测试场景。

bash>echo "imrunning & sleep .5 ; imrunning & sleep .5 ; imrunning & sleep .5 ; imrunning & sleep .5 ; imrunning" > /tmp/initrunning ; chmod +x /tmp/initrunning
bash>/tmp/./initrunning 
Main script block
We're in
Scriptcount:        1 (Including this one)
Main script block
We're in
Scriptcount:        2 (Including this one)
Main script block
too many processes
Main script block
too many processes
Main script block
too many processes
We're in
Scriptcount:        3 (Including this one)
We're in
Scriptcount:        3 (Including this one)
We're in
Scriptcount:        3 (Including this one)
bash