#!/bin/sh set -e -x -v set -o pipefail || true # set some local defaults web_server="${web_server:-'appserver'}" db_server="${db_server:-'replication1'}" database="${database:-'xe150'}" cubrid="${cubrid:-'false'}" # parse command line case "$#" in (0) echo Syntax: echo " $0" "webserver[:port] [ dbserver[:port] [db] ]" echo " $0" "webserver[:port] db@dbserver[:port]" echo exit 1;; (1) if test "$1" = "--help" -o "$1" == "--usage" then "$0" exit else web_server="$1" fi;; (2) web_server="$1" if echo "$2" | grep '@' -l>/dev/null then cubrid=true db_server="$2" database="$(echo "$2" | sed 's#^\([a-zA-Z_0-9]*\)@.*$#\1#')" else db_server="$2" fi;; (3) web_server="$1" db_server="$2" database="$3";; (*) "$0" exit 1;; esac if echo "$db_server" | grep ':' -l>/dev/null then db_port="$(echo "$db_server" | sed 's#^[a-zA-Z0-9.]*:\([0-9]\{2,5\}\)$#\1#')" db_server="$(echo "$db_server" | sed 's#^\([a-zA-Z0-9.]*\):[0-9]\{2,5\}$#\1#')" else db_port=3306 # default mysql port number fi # generate a set of pipes/processes sets= a=0 b=0 while [ $a -lt 2 ] # 20 processes (and pipes) do while [ $b -lt 10 ] do sets="${sets}${sets:+ }$a$b" b=$(($b+1)) done b=0 a=$(($a+1)) done ( # remove all pipes on exit trap 'rm -rf "/tmp/visit_boards"' EXIT mkdir "/tmp/visit_boards" pids_list= # create pipes # start wget processes for the read ends of the pipes # open shell output file descriptors for the write ends of the pipes for p in $sets do fdp="${p#0}" # convert 08 to 8 fdp=$(($fdp+5)) # first 3 file descriptiors are reserved, so start with the 4th fdp_bit=$(($fdp % 2)) # create pipe mkfifo "/tmp/visit_boards/pipe_$p" # connect a new wget process to the read end of the pipe wget --server-response --spider --output-file="visit_$p.log" --input-file="/tmp/visit_boards/pipe_$p" & pids_list="$pids_list${pids_list:+ }$!" # connect the current shell process to the write end of the pipe echo exec "$fdp>>/tmp/visit_boards/pipe_$p">"/tmp/visit_boards/shell_script_pipe" . "/tmp/visit_boards/shell_script_pipe" done # output URLs to the pipes, one line into each pipe in turn if $cubrid then csql -u dba -p arniarules --command='SELECT "domain" FROM xe_sites WHERE site_srl != 0' "$db_server" | sed -n 's#^[[:space:]]*'\''\([a-zA-Z0-9_]*\)'\''$#\1#p' else echo "SELECT domain FROM xe_sites WHERE site_srl != 0" | mysql -u dba --password=arniarules -h "$db_server" -P "$db_port" --skip-column-names "$database" fi \ | { sh_flags="$-" set +x a=0 b=0 while read -r board_name do # output the current site URL to the current file descriptor # (connected to one of the pipes) p="$a$b" fdp="${p#0}" fdp=$(($fdp+5)) fdp_bit=$(($fdp%2)) echo "http://$web_server/$database/$board_name" >&$fdp # advance (a, b) to the next pipe or cycle back to the # first one (0, 0) if (2, 0) is reached b=$(($b+1)) if [ $b -eq 10 ] then b=0 a=$(($a+1)) if [ $a -eq 2 ] then a=0 fi fi done set "-$sh_flags" } if [ "$?" -ne "0" ] then # Old versions of bash (still current on CentOS) do not exit after # errors from the nested (inner) pipe, even with set -e -o pipefail, # but "$?" still indicates a non-zero status exit 4; fi # list the open file descriptors for the process for OPEN_FD in /dev/fd/* do open_fds="${open_fds}${open_fds:+ }${OPEN_FD#/dev/fd/}" done echo "$open_fds" # close write end for all pipes a=0 b=0 while [ $a -lt 2 ] do while [ $b -lt 10 ] do p="$a$b" fdp="${p#0}" fdp=$(($fdp+5)) # a redirection like 9>&- is defined to close file descriptor 9 echo exec "$fdp>&-" >"/tmp/visit_boards/shell_script_pipe" . "/tmp/visit_boards/shell_script_pipe" b=$(($b+1)) done b=0 a=$(($a+1)) done # list the open file descriptors for the process open_fds= for OPEN_FD in /dev/fd/* do open_fds="${open_fds}${open_fds:+ }${OPEN_FD#/dev/fd/}" done echo "$open_fds" watch_pid= if [ -t 0 -a -t 1 ] then watch -n 1 ls -l visit_[0-1][0-9].log & watch_pid="$!" fi error= for pid in $pids_list do wait $pid if [ "$?" -ne 0 ] then error="$error${error:+ }$pid" fi done if test -n "$watch_pid" then # `watch` utility will run until interrupted kill -s INT "$watch_pid" fi if test -n "$error" then echo Child processes "($error)" returned errors. exit 2 fi # EXIT trap shall now remove pipes )