如何检查何时从Bash循环执行Curl PID
我想不出我在OSX上的错误。当我尝试查看Curl何时完成时,进程仍然处于加载状态。我从来没有看到这个消息如何检查何时从Bash循环执行Curl PID,bash,curl,background-process,Bash,Curl,Background Process,我想不出我在OSX上的错误。当我尝试查看Curl何时完成时,进程仍然处于加载状态。我从来没有看到这个消息 #!/bin/bash curl -S -o example.com http://example.com/downloads/example.zip & CURL_PID=$! echo -e "CURL PID = $CURL_PID" while : do sleep 1 if [ -n $(ps -p$CURL_PID -o pid=) ]; then
#!/bin/bash
curl -S -o example.com http://example.com/downloads/example.zip &
CURL_PID=$!
echo -e "CURL PID = $CURL_PID"
while :
do
sleep 1
if [ -n $(ps -p$CURL_PID -o pid=) ]; then
echo "CURL NOT FINISHED"
else
echo "CURL FINISHED"
break
fi
done
运行此命令时,请注意OSX版本的Bash:
#!/bin/bash
PIDX=1
if [ -n $(ps -p$PIDX -o pid=) ]; then
echo "PROCESS 1 IS THERE"
else
echo "PROCESS 1 IS NOT THERE"
fi
…它说过程1就在那里。(每个人都有一个PID 1,所以这只是一个例子。)所以,我知道我的if
语句是正确的。if
行上不需要双引号
请注意,我不能在$CURL\u PID
上使用wait,因为您在这里看不到的是,我还使用OSX的osascript
命令来显示一个对话框,上面写着“下载…”,该对话框上还有一个取消按钮和它自己的$DLG\u PID
,因此我一直循环,直到他们取消该对话框为止(意思是$DLG\u PID
点不见了)或$CURL\u PID
不见了(意思是下载终于完成了,我现在可以运行kill$DLG\u PID
)
在OSX上,请注意,我在curl
语句之前也在这样做
osascript -e 'tell app "System Events" to display dialog "Downloading..." with title "My App Installer" buttons {"Cancel"}' &
因此,如果有人取消该对话框,我将通过PID终止该curl并退出无限循环(并退出bash脚本)。如果他们不取消该对话框,且curl完成,则我将通过PID终止该对话框并退出bash脚本。通常您将使用
等待:
curl http://... &
do_something
wait
echo "CURL has finished"
通常您会使用wait
:
curl http://... &
do_something
wait
echo "CURL has finished"
轮询后台作业的可移植方法是使用kill
内置,并发送信号0
,以查看它是否可交付。kill-0$pid
(其中$pid
是子进程的pid)如果子进程仍在运行,则返回零;如果子进程已死亡,则返回非零。请注意,对于子进程(而不是其他地方启动的随机进程,将PID写入PID文件),这是安全的且仅安全的(从PID回收),原因如下:
每个UNIX进程也有一个父进程。此父进程是启动它的进程,但如果父进程在新进程结束之前结束,则可以更改为init进程。(即,init
将拾取孤立进程。)理解此父/子关系至关重要,因为它是UNIX中可靠进程管理的关键。在父进程等待PID查看其是否结束并检索其退出代码之前,进程的PID将永远不会释放出来供使用。如果父进程结束,进程将返回到init
,w这是他为你做的
这一点很重要,因为有一个主要原因:如果父进程管理其子进程,则可以绝对确定,即使子进程死亡,在父进程等待该PID并注意到子进程死亡之前,其他新进程也不会意外地回收子进程的PID。这为父进程提供了保证子进程的PID始终指向该子进程,无论它是活动的还是“僵尸”。没有其他人有这种保证
当然,较新版本的OS X不使用init
(取而代之的是launchd
),但原理是一样的
顺便说一下,整个页面值得一读:
有鉴于此,下面是一个示例脚本,它实现了您想要的功能(只需要一个URL参数——要下载的URL)
#!/usr/bin/env bash
osascript -e 'tell app "System Events" to display dialog "Downloading..." with title "Downloader" buttons {"Cancel"}' &>/dev/null &
dialog_pid=$!
curl -sSLO "$1" &
curl_pid=$!
timer=0
while kill -0 "$curl_pid" &>/dev/null; do
kill -0 "$dialog_pid" &>/dev/null || { echo "User cancelled download from dialog."; kill "$curl_pid" &>/dev/null; exit 1; }
sleep 1
(( timer++ ))
echo "Been downloading for $timer seconds..."
done
echo "Finished."
kill "$dialog_pid" &>/dev/null
wait &>/dev/null
运行它:
> ./download https://github.com/torvalds/linux/archive/v4.4-rc2.tar.gz
Been downloading for 1 seconds...
Been downloading for 2 seconds...
<omitted>
Been downloading for 38 seconds...
Finished.
丑陋的是,杀死osascript
作业的PID并不会关闭对话框……我无法解决这个问题,因为我非常害怕AppleScript。轮询后台作业的可移植方法是使用kill
内置程序,并发送信号0
,查看它是否可交付。kill-0$pid
(其中,$pid
是子进程的pid)将在子进程仍在运行时返回零,如果子进程已经死亡,则返回非零。请注意,对于子进程(而不是在别处启动的、pid写入pid文件的随机进程),这是安全的,并且是唯一安全的(pid回收),原因如下:
每个UNIX进程也有一个父进程。此父进程是启动它的进程,但如果父进程在新进程结束之前结束,则可以更改为init进程。(即,init
将拾取孤立进程。)理解此父/子关系至关重要,因为它是UNIX中可靠进程管理的关键。在父进程等待PID查看其是否结束并检索其退出代码之前,进程的PID将永远不会释放出来供使用。如果父进程结束,进程将返回到init
,w这是他为你做的
这一点很重要,因为有一个主要原因:如果父进程管理其子进程,则可以绝对确定,即使子进程死亡,在父进程等待该PID并注意到子进程死亡之前,其他新进程也不会意外地回收子进程的PID。这为父进程提供了保证子进程的PID始终指向该子进程,无论它是活动的还是“僵尸”。没有其他人有这种保证
当然,较新版本的OS X不使用init
(取而代之的是launchd
),但原理是一样的
顺便说一下,整个页面值得一读:
有鉴于此,下面是一个示例脚本,它实现了您想要的功能(只需要一个URL参数——要下载的URL)
#!/usr/bin/env bash
osascript -e 'tell app "System Events" to display dialog "Downloading..." with title "Downloader" buttons {"Cancel"}' &>/dev/null &
dialog_pid=$!
curl -sSLO "$1" &
curl_pid=$!
timer=0
while kill -0 "$curl_pid" &>/dev/null; do
kill -0 "$dialog_pid" &>/dev/null || { echo "User cancelled download from dialog."; kill "$curl_pid" &>/dev/null; exit 1; }
sleep 1
(( timer++ ))
echo "Been downloading for $timer seconds..."
done
echo "Finished."
kill "$dialog_pid" &>/dev/null
wait &>/dev/null
运行它:
> ./download https://github.com/torvalds/linux/archive/v4.4-rc2.tar.gz
Been downloading for 1 seconds...
Been downloading for 2 seconds...
<omitted>
Been downloading for 38 seconds...
Finished.
丑陋的是,杀死osascript
作业的PID并不会关闭对话框……我无法解决这个问题,因为我非常害怕AppleScript。首先,“Bash bug”这个短语并不是你想要的意思……其次,那是什么意思?#!
拜托。第三,$(附言)
需要引用。一旦