bash 中的并行进程,使用 Ctrl C 终止
Parallel processes in bash, kill with Ctrl C
刚刚制作了我的第一个 bash 脚本。它为特定目录中的每个文件夹并行生成一个 http-server
进程。
这是我的:
PORT=8001
cd websitesfolder
for d in */ ; do
http-server $d -p $PORT &
let "PORT++"
done
这确实产生了 http-server
s,但是当我使用 Ctrl C 退出时,进程没有被终止。
我先在没有循环的情况下实现了这个,然后添加 && fg
我能够使用 Ctrl+C
终止进程
http-server dir1 -p 8001 & http-server dir2 -p 8002 && fg
我的循环解决方案是否有类似的可能?
编辑:系统为 macOS
一个简单的方法——尽管不完全可靠,如果一个进程死了并且有其他东西被分配了它的 PID 号——就是简单地维护一个 PID 数组:
#!/usr/bin/env bash
pids=( )
port=8001
graceful_shutdown() {
(( ${#pids[@]} )) && kill "${pids[@]}"
}
cd websitesfolder || exit
for d in */ ; do
http-server "$d" -p "$port" & pids+=( "$!" )
(( ++port ))
done
trap graceful_shutdown EXIT
for pid in "${pids[@]}"; do
wait "$pid" || (( retval |= $? ))
done
exit "$retval"
更好的方法是为每个端口设置一个锁定文件,或者使用 fuser -k
直接终止实际保持端口打开的进程,而不是假设您知道 PID:
#!/usr/bin/env bash
graceful_shutdown() {
fuser -k "$lockdir"/*
}
lockdir=/var/run/mydir # this needs to exist
port=8001
pids=( )
cd websitesfolder || exit
for d in */; do
(exec 3>"$lockdir/$port" &&
flock -x 3 &&
exec http-server "$d" -p "$port") & pids+=( "$!" )
done
trap graceful_shutdown EXIT
for pid in "${pids[@]}"; do
wait "$pid" || (( retval |= $? ))
done
exit "$retval"
刚刚制作了我的第一个 bash 脚本。它为特定目录中的每个文件夹并行生成一个 http-server
进程。
这是我的:
PORT=8001
cd websitesfolder
for d in */ ; do
http-server $d -p $PORT &
let "PORT++"
done
这确实产生了 http-server
s,但是当我使用 Ctrl C 退出时,进程没有被终止。
我先在没有循环的情况下实现了这个,然后添加 && fg
我能够使用 Ctrl+C
http-server dir1 -p 8001 & http-server dir2 -p 8002 && fg
我的循环解决方案是否有类似的可能?
编辑:系统为 macOS
一个简单的方法——尽管不完全可靠,如果一个进程死了并且有其他东西被分配了它的 PID 号——就是简单地维护一个 PID 数组:
#!/usr/bin/env bash
pids=( )
port=8001
graceful_shutdown() {
(( ${#pids[@]} )) && kill "${pids[@]}"
}
cd websitesfolder || exit
for d in */ ; do
http-server "$d" -p "$port" & pids+=( "$!" )
(( ++port ))
done
trap graceful_shutdown EXIT
for pid in "${pids[@]}"; do
wait "$pid" || (( retval |= $? ))
done
exit "$retval"
更好的方法是为每个端口设置一个锁定文件,或者使用 fuser -k
直接终止实际保持端口打开的进程,而不是假设您知道 PID:
#!/usr/bin/env bash
graceful_shutdown() {
fuser -k "$lockdir"/*
}
lockdir=/var/run/mydir # this needs to exist
port=8001
pids=( )
cd websitesfolder || exit
for d in */; do
(exec 3>"$lockdir/$port" &&
flock -x 3 &&
exec http-server "$d" -p "$port") & pids+=( "$!" )
done
trap graceful_shutdown EXIT
for pid in "${pids[@]}"; do
wait "$pid" || (( retval |= $? ))
done
exit "$retval"