proc1.sh

proc1.sh

proc1.sh

#!/bin/sh
touch /tmp/proc1.signature.mutex
#do something for long time
sleep 100 
rm -rf /tmp/proc1.signature.mutex

proc2.sh

#!/bin/sh
touch /tmp/proc2.signature.mutex
#do something for long time
sleep 100 
rm -rf /tmp/proc2.signature.mutex

proc3.sh

#!/bin/sh
touch /tmp/proc3.signature.mutex
#do something for long time
sleep 100 
rm -rf /tmp/proc3.signature.mutex

核心文件

现在有没有办法等待使用循环或其他方式删除 /tmp/proc[?][*].signature.mutex 所有此类文件,然后继续进一步执行

如何实现core.sh的目标

答案1

互斥锁是一种互斥锁。您的procN.sh脚本在“锁定”之前从不测试互斥锁是否由另一个进程持有。

如果您core.sh启动其他脚本,那么它很容易等待它们完成:

#!/bin/sh

./proc1.sh &
./proc2.sh &
./proc3.sh &

wait

# other processing

这完全消除了对锁定文件的需要。如果不可能,请考虑

#!/bin/sh

while [ -e "$HOME/locks/proc1.signature.mutex" ] ||
      [ -e "$HOME/locks/proc2.signature.mutex" ] ||
      [ -e "$HOME/locks/proc3.signature.mutex" ]
then
    echo 'waiting...'
    sleep 10
done

# other processing

为了避免脚本因非自然原因死亡而留下文件procN.sh,请使用陷阱:

#!/bin/sh

lockfile="$HOME/locks/proc1.signature.mutex"

while [ -e "$lockfile" ]; do
    echo 'Can not get lock. Waiting...' >&2
    sleep 10
done
## alternatively:
# [ -e "$lockfile" ] && { echo 'something is wrong' >&2; exit 1; }

trap 'rm "$lockfile"; exit' EXIT INT TERM HUP
touch "$lockfile"

# etc.
# no need to rm the lock file at the end

-e "$lockfile"请注意,测试和测试之间有一个空格,touch其中另一个进程可能会锁定同一文件。

为了避免这种情况,请使用锁目录反而:

#!/bin/sh

lockdir="$HOME/locks/proc1.signature.mutex"

while ! mkdir "$lockdir"; do
    echo 'Can not get lock. Waiting...' >&2
    sleep 10
done

trap 'rmdir "$lockdir"; exit' EXIT INT TERM HUP

# etc.
# no need to rmdir the lock dir at the end

您也可以以类似的方式使用符号链接。

请注意,我使用了下面的路径$HOME作为锁定文件/目录。如果使用/tmp,任何用户都可能通过简单地创建正确的文件/目录来锁定您的脚本,使其无法运行。

答案2

我写https://github.com/acbits/sema正是出于这个原因。很久没关注SE了,才注意到这个问题。我只在Linux上测试过

答案3

使用https://github.com/acbits/sema在 shell 脚本中使用信号量。

 A.sh 
_____________________________________________
#!/bin/sh

echo A.sh started
sema -c S1
./B.sh &
echo A.sh more work
echo waiting for B.sh to finish
sema -w S1
echo B.sh finished execution
echo A.sh do more work
# cleanup semaphores
sema -d S1
_____________________________________________

B.sh
_____________________________________________
#!/bin/sh

echo Hello from B.sh
sleep 5
sema -r S1
echo Bye bye from B.sh
____________________________________________

相关内容