2

所以我有这个代码:

uthreads=4                                                                                                            
x=1                                                                                                                   

cd ./wxWidgets/wxWidgets/build-win                                                                                    

for upxs in $(ls ./lib/*.dll)                                                                                         
do                                                                                                                    
    while [ true ] ; do                                                                                           
            if [ $x -lt $uthreads ] ; then                                                                        
                    x=$((x+1))                                                                                    
                    (upx -qqq --best --color $upxs; x=$((x-1))) &                                                 
                    break                                                                                         
            fi                                                                                                    
            sleep 1                                                                                               
    done                                                                                                          
done                                                                                                                  
x=$((x=1))

问题在于括号中的变量被修改。当然,这不会按预期工作,因为变量永远不会被发送回父 shell。所以我的问题是你是怎么做到的?该变量必须在 upx 命令完成后递增,无论其退出状态如何。所以一个简单的 && 或 || 不会在这里工作。并且你不能在 upx 之后使用单个 & 这里;因为然后该过程在后台运行并立即更改变量...

所以我实际上被卡住了,可以使用一些帮助......

4

2 回答 2

0

假设您试图通过控制在后台运行的程序副本数量来“控制”程序的活动,请查看该xargs命令。我的系统没有upx安装,所以我可以推荐的最好的代码示例是

uthreads=4                                                                                                            
cd ./wxWidgets/wxWidgets/build-win

ls ./lib/*.dll | xargs -I{} -P $uthreads upx -qqq --best --color {} 
   ^                    ^    ^           ^   ^                   ^
   +>your list          |    |           |   |                   |
                        |    |           |   |                   +> item from your lst
                        |    |           |   +> your cmd's opts
                        |    |           +> your cmd
                        |    + xargs opt for # of processes
                        + xargs  option to indicate what string to replace with           

使用xargs --help来查看所有选项,man xargs如果您很幸运能够深入了解使用情况,并在网络和此处搜索更多使用示例。维基百科文章是一个好的开始。

我希望这有帮助

于 2011-12-27T23:47:38.800 回答
0

首先, this:while [ true ]是错误的,true是一个命令,所以[你不需要两个都在这里while true; do(并且[[在 bash 中使用,另一个只用于 POSIX-sh)。

this:for upxs in $(ls ./lib/*.dll)也是错误的,而且更严重;我会给你一些关于所有这些信息的链接,但现在只做:for upxs in ./lib/*.dll

另一个重要的错误是你没有引用你的变量,每一个变量都必须双引号,如果你从这篇文章中学到了什么,请让它如​​此。

现在关于您的特定问题,整个方法是错误的,您无法做您想做的事情,因为您不知道哪个过程将首先结束,您等待特定的过程或等待所有过程。

还请注意,您正在使用同一个文件运行四个进程,我确定您的意图是并行处理 4 个不同的文件,并且您也不等待它们完成,很可能在您的脚本结束后您的进程被杀死。

次优但简单的解决方案是让 4 个进程并行运行,并等待它们全部完成,然后再开始 4 个,这是通过这个来完成的(类似于您当前的方法):

#!/bin/bash

uthreads=4

cd ./wxWidgets/wxWidgets/build-win
upxs=(lib/*.dll)

i=0
while ((i<${#upxs[@]})); do
    for ((x=0; x<uthreads; x++)); do
        [[ ${upxs[i+x]} ]] || break
        upx -qqq --best --color "${upxs[i+x]}" &
    done
    i=$((i+x))
    wait
done

现在,这可能不足以让您满意 :) 所以始终实现 4 个正在运行的进程的方法是这样的(使用 PID):

#!/bin/bash

uthreads=4

cd ./wxWidgets/wxWidgets/build-win
upxs=(lib/*.dll)

i=0 pids=()
while [[ ${upxs[i]} ]]; do
    while ((${#pids[@]}<uthreads)); do
        upx -qqq --best --color "${upxs[i]}" & pids+=($!)
        [[ ${upxs[++i]} ]] || break
    done
    sleep .1
    pids=($(for pid in "${pids[@]}"; do kill -0 $pid && echo $pid; done))
done
wait

现在这是我承诺的链接:

于 2011-12-28T00:46:45.677 回答