Art*_*man 0 unix bash shell wc
我正在UNIX上做一个入门课程 - 其中一部分是bash脚本.我似乎已经理解了这些概念,但在这个特殊的问题上我无法解决这个问题.
我有一个txt文件,包含1列随机用户名.然后将该txt文件用作我的bash脚本的参数,理想情况下使用用户名来获取页面并计算该页面上的字符数.如果页面成功获取,则随后将字符计数与用户名一起保存在不同的txt文件中.
这是一个代码:
#!/bin/bash
filename=$1
while read username; do
curl -fs "http://example.website.domain/$username/index.html"
if [ $? -eq 0 ]
then
x=$(wc -m)
echo "$username $x" > output.txt
else
echo "The page doesn't exist"
fi
done < $filename
Run Code Online (Sandbox Code Playgroud)
现在我遇到的问题是,在一次成功获取之后,它会对字符进行计数,将它们输出到文件中,然后完成循环并退出程序.如果我特意删除"wc -m"位,代码运行完全正常.
问:是否应该发生这种情况,我应该如何解决这个问题呢?或者我在其他地方犯了错误?
显示的代码不符合您的想法(并在您的问题中声明).
您的curl命令将获取Web并将其抛出到stdout:您不会保留此信息以供将来使用.然后,你wc没有任何参数,所以它开始从stdin读取.在stdin中,您有来自的用户名列表$filename,因此计算的数字不是Web的字符,而是文件的剩余字符.一旦考虑到这一点,stdin中没有任何东西可以被读取,所以循环结束是因为它到达了文件的末尾.
您正在寻找类似的东西:
#!/bin/bash
filename="$1"
set -o pipefail
rm -f output.txt
while read username; do
x=$(curl -fs "http://example.website.domain/$username/index.html" | wc -m)
if [ $? -eq 0 ]
then
echo "$username $x" >> output.txt
else
echo "The page doesn't exist"
fi
done < "$filename"
Run Code Online (Sandbox Code Playgroud)
这里,获取的页面直接输入到wc.如果curl失败,你将看不到(默认情况下,一系列管道命令的退出代码是最后一个命令的退出代码),因此我们使用set -o pipefail一个不同于零的值来获取最右边退出代码的退出代码.现在您可以检查一切是否正常,在这种情况下,您可以编写结果.
我还添加了一个rm输出文件,以确保我们不会增加现有的输出文件,并将重定向更改为输出文件,以避免在每次迭代时重新创建文件,最后以最后一次迭代的结果(感谢@tripleee注意到这一点).
更新(按流行要求):
模式:
<cmd>
if [ $? -eq 0 ]...
Run Code Online (Sandbox Code Playgroud)
通常是一个坏主意.最好去:
if <cmd>...
Run Code Online (Sandbox Code Playgroud)
所以如果切换到以下情况会更好:
if x=$(curl -fs "http://example.website.domain/$username/index.html" | wc -m); then
echo...
Run Code Online (Sandbox Code Playgroud)