【问题标题】:Spinning up multiple tmux sessions in bash在 bash 中启动多个 tmux 会话
【发布时间】:2019-10-18 15:32:09
【问题描述】:

我有一个 python 脚本,my_python_script,它需要输入日期。 我有一个 bash 脚本,它在 for 循环中为一系列日期调用这个 python 脚本。我尝试在 for 循环中创建一个命名会话,但这会嵌套 tmux 会话:

call_runner_date_range() {
    start=$1
    end=$2

    start=$(date -d $start +%Y%m%d)
    end=$(date -d $end +%Y%m%d)

    while [[ $start -le $end ]]
    do
            tmux new -s $start
            start=$(date -d"$start + 1 day" +"%Y%m%d")
            formatted_date=$(date -d $start +%m-%d-%Y)
            python -m my_python_script --analysis-date=$formatted_date
    done
}

call_runner_date_range '2016-12-31' '2019-08-15'

我想修改这个 bash 脚本,为每个日期打开一个新的 tmux 会话(我想使用 tmux 的原因是我可以监控输出日志),以便这些脚本可以并行运行。我该怎么做,有没有比使用 tmux 更好的选择?

【问题讨论】:

  • 你是问send_keys怎么用?
  • @jeremysprofile- tmux 是我对最好的方法的理解,但如果你认为你的建议可能是一个更好的选择,你能把它作为解决方案发布吗?我之前没用过nohupsend_keys
  • tmux 似乎是一个很好的解决方案,因为我仍然想监控当前打印到标准输出的日志(编辑问题以反映这一点)
  • 当然,但是 tmux 会为程序打开一个 interactive 会话,它很难在超过 600 个正在运行的进程中导航。将每个 python 脚本的输出重定向到某个目录中的每个唯一文件不是更容易吗?这将只是python ... > "some_dir/log_$start.log" & 或将它们全部重定向到一个文件,每一行都以每个进程的唯一字符串作为前缀。
  • tmux new 不会创建 nested 会话,因为您的脚本无法移动到 tmux 会话中;它启动的任何 tmux 副本都是子进程; UNIX 通常不允许重父化,虽然将 stdin/stdout/stderr 更改为指向不同的 FD 集是可能的,但它涉及到一堆棘手的魔法。

标签: bash tmux


【解决方案1】:

要在后台启动进程,请使用& 作为命令的终止字符。使用> 将进程的标准输出重定向到文件。如需参考,您可以查看bash manual List of commandsbash manual redirections,但网上提供了许多资源。

所以脚本会变成:

call_runner_date_range() {
    start=$1
    end=$2

    start=$(date -d $start +%Y%m%d)
    end=$(date -d $end +%Y%m%d)

    while [[ $start -le $end ]]
    do
            start=$(date -d"$start + 1 day" +"%Y%m%d")
            formatted_date=$(date -d $start +%m-%d-%Y)
            python -m my_python_script --analysis-date=$formatted_date > log_$start.log &
    done
}

call_runner_date_range '2016-12-31' '2019-08-15'

您可以使用内置的wait shell 来等待当前 bash shell 中所有当前仍在运行的后台进程。或者,您可以使用$! 保存每个后台作业进程 id PID,并指定您要等待的 pid 列表。

childs=() # bash array, initializing to empty

# then later:
python -m my_python_script --analysis-date=$formatted_date > log_$start.log &
childs+=($!)  # append the background jobs pids name to bash array

# then later
wait "${childs[0]}" # wait for first background job in childs array
wait "${childs[@]}" # wait for all background jobs in childs array

请注意,您可能有兴趣使用xargs,它可以(在大多数实现中)为每一行输入并行执行命令,或者令人惊叹的GNU parallel,它只是一个外壳工具,可以尽可能简单地并行执行多个作业.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多