异步 Bash 脚本

5

我看到过一些例子,但是无法将它们适应我的情况。

我有一个调用长时间运行命令的脚本,但我想定期(比如每秒钟)获取该调用的状态。例如:

#!/bin/bash

curl localhost:9200/my_index/_forcemerge?max_num_segments=2 &

while [ command is running ]; do
  curl -XGET localhost:9200/_cat/shards/my_index?v&h=index,shard,prirep,segments.count
  sleep 1
done

echo "finished!"

通过这种方式获取子进程的状态是否可能?

编辑:澄清我实际上正在做什么。实际上是对Elasticsearch集群执行两个curl命令。长时间运行的命令将数据段合并在一起,“状态”命令将获取当前段数。


只有在长时间运行的命令完成后,您才能获取其状态!需要更多信息,command.sh 在后台运行多个命令还是只有一个命令?它通常需要多长时间才能完成? - Inian
是的,这是可能的,但您没有明确说明状态的含义?您是在谈论完成吗?您需要帮助的部分是示例中的哪一部分?是while [ command is running ]部分还是/script/that/gets/status.sh部分? - kamikaze
好的,为了澄清,长时间运行的命令是一个curl命令。通常需要大约10分钟。状态是由curl命令调用的合并的状态(实际上将是另一个curl命令)。 - dwjv
1个回答

11

我认为最安全的方法是保存子进程的进程ID,然后定期检查它是否仍在运行:

#!/bin/bash

mycommand &
child_pid=$!

while kill -0 $child_pid >/dev/null 2>&1; do
    echo "Child process is still running"
    sleep 1
done

echo "Child process has finished"
变量$!将保存在后台启动的最后一个进程的进程ID。 kill -0不会向进程发送信号,它只会在给定的进程ID存在且属于执行kill命令的用户时返回零退出状态。
也可以使用pgrep来解决问题,但这可能会更加“不安全”,因为必须注意不要捕获任何类似运行中的进程。

1
我发现 kill -0 很少出现奇怪的副作用。最好检查 /proc/$pid 是否是一个目录。不过这仍然是一个好答案。 - Linus Kleen
@LinusKleen 请解释一下。而且,依赖于 /proc 的存在会使脚本天生不可移植。 - Kusalananda

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接