#!/bin/bash # ref: https://blog.csdn.net/spch2008/article/details/51433353 token(){ pid=$1 # 判斷是否有傳入pid if [ -z "${pid}" ] then echo "please input pid" exit 1 fi # 設置並發數,默認為5 concurrency=5 if [ -n "$2" ] then concurrency=$2 echo "Concurrency: $2" fi # 創建有名管道,如果fd1不存在則創建 [ -e /tmp/fd1 ] || mkfifo /tmp/fd1 # 創建文件描述符,以可讀(<)可寫(>)的方式關聯管道文件,這時候文件描述符999就有了有名管道文件的所有特性 # 為了讓程序有一定的擴展性,不想寫死fd,因而引入了變量。 # 因而引入eval命令,強制shell進行變量展開。 # eval exec "${fd}>file"簡單的說,eval將右邊參數整體作為一個命令,進行變量的替換,然后將替換后的輸出結果給shell去執行。 eval exec "${pid}<>/tmp/fd1" # 關聯后的文件描述符擁有管道文件的所有特性,所以這時候管道文件可以刪除,我們留下文件描述符來用就可以了 [ -e /tmp/fd1 ] && rm -f /tmp/fd1 # 初始化並行數 for ((i=1;i<=3;i++)) do # &999代表引用文件描述符999,這條命令代表往管道里面放入了一個"令牌" echo ${i}>&${pid} done } main(){ pid=5 start_time=`date +%s` # 生成管道文件 token ${pid} # 循環獲取服務包名 for file_name in `ls /root/spark/dependency/*.jar|head -10` do # 獲取令牌 read -u${pid} name { # 根據文件名去掉版本后綴,獲得服務名 # svc_name=${file_name%0.0.1*} # 獲取啟動參數 # get_para # 執行重啟 # one_restart # 這一次命令執行到最后,把令牌放回管道 echo "pipi_num: ${name}, file_name: ${file_name}" sleep 1 echo ${name}>&${pid} } & done wait # 定義腳本運行的結束時間 stop_time=`date +%s` echo "TIME:`expr ${stop_time} - ${start_time}`" # 關閉文件描述符的讀 eval exec "${pid}<&-" # 關閉文件描述符的寫 eval exec "${pid}>&-" } main