检查死链接(例如指向404错误的链接)的一个非常好的工具是wget --spider
。但是,我有一个稍微不同的用例,我生成一个静态网站,并希望在上传之前检查损坏的链接。更确切地说,我想检查两者:
<a href="some/file.pdf">file.pdf</a>
绝对链接,最有可能是<a href="http://example.com">example</a>
等外部网站。
我尝试wget --spyder --force-html -i file-to-check.html
,它读取本地文件,将其视为HTML并跟随每个链接。不幸的是,它无法处理本地HTML文件中的相对链接(使用Cannot resolve incomplete link some/file.pdf
时出错)。我尝试使用file://
,但wget
不支持。
目前,我有一个黑客,它基于通过python3 http.serve
运行本地网络服务器并通过HTTP检查本地文件:
python3 -m http.server &
pid=$!
sleep .5
error=0
wget --spider -nd -nv -H -r -l 1 http://localhost:8000/index.html || error=$?
kill $pid
wait $pid
exit $error
由于以下几个原因,我对此并不满意:
我需要此sleep .5
来等待网络服务器准备就绪。如果没有它,脚本会失败,但我无法保证0.5秒就足够了。我希望有一种方法可以在服务器准备就绪时启动wget
命令。
相反,这个kill $pid
感觉很难看。
理想情况下,python3 -m http.server
可以选择在服务器准备就绪时运行命令,并在命令完成后自行关闭。通过编写一些Python听起来可行,但我想知道是否存在更清晰的解决方案。
我错过了什么吗?有更好的解决方案吗?我在我的问题中提到了wget
,因为它几乎完全符合我的要求,但使用wget
不是我的要求(也不是python -m http.server
)。我只需要在Linux上运行一些易于操作和自动化的东西。
答案 0 :(得分:10)
所以我认为你正朝着正确的方向前进。我会使用wget
和python
,因为它们是许多系统上两个随时可用的选项。而最重要的是它可以为您完成工作。现在你想要的是从那个过程的Serving HTTP on 0.0.0.0
中听取stdout
。
所以我会使用下面的内容开始这个过程
python3 -u -m http.server > ./myserver.log &
注意我在这里用于无缓冲输出的-u
,这非常重要
现在接下来正在等待此文字显示在myserver.log
timeout 10 awk '/Serving HTTP on 0.0.0.0/{print; exit}' <(tail -f ./myserver.log)
所以10
秒是你的最长等待时间。休息是不言自明的。接下来关于您的kill $pid
。我不认为这是一个问题,但如果你想让它更像用户的方式那么我会把它改成
kill -s SIGINT $pid
这相当于您在启动程序后处理CTRL+C
。我也会使用下面的内容处理SIGINT
我的bash脚本
以上基本上添加到bash脚本的顶部以处理您使用CTRL+C
或外部终止信号杀死脚本
#!/bin/bash
exit_script() {
echo "Printing something special!"
echo "Maybe executing other commands!"
trap - SIGINT SIGTERM # clear the trap
kill -- -$$ # Sends SIGTERM to child/sub processes
}
trap exit_script SIGINT SIGTERM
答案 1 :(得分:0)
Tarun Lalwani的回答是正确的,并且根据给出的建议,可以编写一个简洁的shell脚本(依赖于Python和awk)。另一个解决方案是完全用Python编写脚本,给出一个稍微冗长但可以说更清晰的脚本。服务器可以在一个线程中启动,然后执行检查网站的命令,最后关闭服务器。我们不需要解析文本输出,也不需要再向外部进程发送信号。因此,脚本的关键部分是:
id
我编写了一个稍高级的脚本(在此基础上进行了一些命令行选项解析)并将其发布为:https://gitlab.com/moy/check-links