我正在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
现在我这里的问题是,一次成功获取后,它会计算字符,将它们输出到文件中,然后完成循环并退出程序。如果我专门删除“ wc -m”位,则代码运行得很好。
问:这是否应该发生,我应该如何解决该问题以实现我的目标?还是我在其他地方犯了错误?
答案 0 :(得分:5)
显示的代码没有按照您的想法(并在您的问题中声明)。
您的curl
命令获取网络并将其扔到stdout:您没有保留此信息以备将来使用。然后,您的wc
没有任何参数,因此它开始从stdin中读取。并且在stdin中,您具有$filename
中的用户名列表,因此要计算的数字不是网络字符,而是文件的其余字符。一旦解决了这个问题,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"
在这里,获取的页面被直接馈送到wc
。如果curl
失败,您将不会看到(默认情况下,一系列管道命令的退出代码是最后一个命令的退出代码),因此我们使用set -o pipefail
来获取rm
的退出代码。最右边的退出代码,其值不同于零。现在,您可以检查一切是否正常,在这种情况下,您可以写入结果。
我还添加了输出文件的<cmd>
if [ $? -eq 0 ]...
,以确保我们没有增加现有文件的质量,并将输出文件的重定向更改为附加文件,以避免在每次迭代时重新创建文件并结束最后一次迭代的结果(感谢@tripleee指出了这一点)。
更新(根据普遍要求):
模式:
if <cmd>...
通常是个坏主意。最好去:
if x=$(curl -fs "http://example.website.domain/$username/index.html" | wc -m); then
echo...
因此,最好切换到以下位置:
enctype="multipart/form-data"
答案 1 :(得分:1)
默认情况下,wc
程序(以及在Linux上可以找到的许多其他实用程序)期望其输入在stdin
(标准输入)上提供,并向{{ 1}}(标准输出)。
在您的情况下,您希望stdout
对wc
调用的结果进行运算。您可以通过将curl
的结果存储在变量中并将变量的内容传递到curl
wc
或者,您可以将整个命令放在一个管道中,这可能更好(尽管您可能想要data=$(curl -fs "http://example.website.domain/$username/index.html")
...
x=$(echo "$data" | wc -m)
来捕获来自set -o pipefail
的错误):
curl
否则,如@Dominique所述,您的x=$(curl -fs "http://example.website.domain/$username/index.html" | wc -m)
将无限期等待直到获得一些输入。
答案 2 :(得分:0)
正如其他人已经指出的那样,只有#!/bin/bash
filename=$1
# Use read -r
while read -r username; do
if page=$(curl -fs "http://example.website.domain/$username/index.html"); then
# Feed the results from curl to wc
x=$(wc -m <<<"$page")
# Don't overwrite output file on every iteration
echo "$username $x"
else
# Include parameter in error message; print to stderr
echo "$0: The page for $username doesn't exist" >&2
fi
# Note proper quoting
# Collect all output redirection here, too
done < "$filename" >output.txt
会“挂起”,因为它希望您在stdin上提供输入。
您似乎正在寻找类似的东西
CustomPreference