0

我正在使用 Python 通过简单地使用 Python 的“os”库来执行外部程序:

os.system("./script1") # script1 generates several log files and the most important for me is "info.log" !
os.system("./script2") # script2 uses the output from script1

问题是这些脚本在 50000 元素“for loop”中,“script1”需要至少 2 分钟才能完成它的工作(它有固定的持续时间)在前 1-2 秒我可以找出我是否需要输出数据或不通过查看“info.log”文件。然而,由于“script1”是一个已经编译好的程序,我不能修改它,我必须等到它完成。

我正在考虑 Bash 中的一种方法,它允许我同时运行两个进程:一个是启动./script1,另一个是监视“info.log”文件中的任何变化......
如果“info.log”有已更新或更改大小,则第二个脚本应终止两个进程。

就像是:

os.system("./mercury6 1 > ./energy.log 2>/dev/null & sleep 2 & if [ $(stat -c %s ./info.log) -ge 1371]; then kill %1; else echo 'OK'; fi")

– 这不起作用...

请,如果有人知道一种方法,请告诉我!

4

5 回答 5

0

它已经完成 !不是那么优雅,但它的工作原理!这是代码:

#!/bin/bash

[ -n "$BASH_VERSION" ] || { echo "你需要 Bash 来运行这个脚本。" 出口 1 }

# set +o monitor ## 禁用作业控制。

INFO_LOG="./info.out"

# 使用脚本运行第一个进程。

./mercury6 1 > ./energy.log 2>/dev/null &mercury6_PID=$! 拒绝“$mercury6_PID”

# 运行第二个进程。

( sleep 5 function kill_processes { echo "Killing both processes." kill "$mercury6_PID" exit 1 } while IFS= read -r LINE; do
[[ "${LINE}" == "ejected" ]] || [[ " ${LINE}" == "完成。" ]] && { echo "$INFO_LOG 已更改。" killall tail kill_processes } 完成 < <(tail -f "$INFO_LOG") )

#&

#disown "$!"

如果您有任何建议,非常欢迎!顺便说一句,我也会尝试在 python 中使用 os.fork() 来实现。再次感谢!

于 2013-08-14T21:53:54.717 回答
0

你可以试试这个。告诉我 script1 是否在运行时暂停,以便我们尝试进一步配置它。

#!/bin/bash

[ -n "$BASH_VERSION" ] || {
    echo "You need Bash to run this script."
    exit 1
}

set +o monitor ## Disable job control.

INFO_LOG='./info.log'

if [[ ! -f $INFO_LOG ]]; then
    # We must create the file.
    : > "$INFO_LOG" || {
        echo "Unable to create $INFO_LOG."
        exit 1
    }
fi

read FIRSTTIMESTAMP < <(stat -c '%s' "$INFO_LOG") && [[ $FIRSTTIMESTAMP == +([[:digit:]]) ]] || {
    echo "Unable to get stat of $INFO_LOG."
    exit 1
}

# Run the first process with the script.

./script1 &
SCRIPT1_PID=$!
disown "$SCRIPT1_PID"

# Run the second process.

(
    function kill_processes {
        echo "Killing both processes."
        kill "$SCRIPT1_PID"
        exit 1
    }

    [[ -f $INFO_LOG ]] || {
        echo "File has been deleted."
        kill_processes
    }

    read NEWTIMESTAMP < <(stat -c '%s' "$INFO_LOG") && [[ $NEWTIMESTAMP == +([[:digit:]]) ]] || {
        echo "Unable to get new timestamp of $INFO_LOG."
        kill_processes
    }

    [[ NEWTIMESTAMP -ne FIRSTTIMESTAMP ]] || {
        echo "$INFO_LOG has changed."
        kill_processes
    }

    sleep 4s
) &

disown "$!"

您可能还想在这里查看一些其他类似的解决方案:带有 netcat 的 linux 脚本在 x 小时后停止工作


(
    function kill_processes {
        echo "Killing both processes."
        kill "$mercury6_PID"
        exit 1
    }
    while IFS= read -r LINE; do
        [[ "${LINE}" == "ejected" ]] && {  ## Perhaps it should be == *ejected* ?
            echo "$INFO_LOG has changed."
            kill_processes
        }
    done < <(tail -f "$INFO_LOG")
) &

disown "$!"
于 2013-08-14T09:40:38.243 回答
0
import os
import time

os.system("script1")

while True: # Now this would run in 10 sec cycles and checks the output of the logs
   try:     # And you don't have the wait the whole 2 mins to script1 to be ready
       o = open("info.log", "r") # or add os.system("script2") here
       # Add here more logs
       break
   except:
       print "waiting script1 to be ready.."
       time.sleep(10) # Modify (seconds) to be sufficient to script1 to be ready
       continue
于 2013-08-14T08:55:04.850 回答
0

我建议使用subprocess, 结合这个描述如何杀死 bash 脚本的答案以及一些监视文件的方法,比如watchdog或简单的轮询循环。

于 2013-08-14T09:03:28.740 回答
-1

这里(谷歌是你的朋友)。您可以使用 & 符号使进程成为后台任务,然后使用wait让父进程等待其子进程。

于 2013-08-14T08:23:31.293 回答