【问题标题】:for loop: commands start from begin every timefor 循环:命令每次都从 begin 开始
【发布时间】:2014-03-16 22:05:47
【问题描述】:

我编写了以下 bash 脚本来检查来自 domain.list 的域列表和来自 dir.list 的多个目录。

@ 是第一个域,它首先尝试在以下位置查找文件 http://example.com 如果成功脚本完成并退出没有问题。

如果失败就去检查它 https://example.com 如果没问题,脚本完成并退出, 如果不 检查它在 http://example.com/$list 的不同目录。

如果文件找到脚本完成并退出,如果找不到 然后去检查它 https://example.com/$list的不同目录

但问题是,当第一次检查失败和第二次检查失败时,它会进入第三次检查,但它一直在循环,在第三个命令和第四个命令,告诉它找到文件或目录列表完成。

我希望脚本在到达第三个命令时运行它并在目录列表中检查它告诉列表完成而不是第四个命令告诉它完成

在我的脚本中,它不断检查多个目录中的单个域,每次检查一个新目录时,它都会从 bagain 启动整个脚本并从头开始再次运行第一个命令和第二个命令,我不需要那个,大损失时间

谢谢

#!/bin/bash
dirs=(`cat dir.list`)
doms=( `cat domain.list`)
for dom in "${doms[@]}"
do
for dir in "${dirs[@]}"
do
target1="http://${dom}"
target2="https://${dom}"
target3="http://${dom}/${dir}"
target4="https://${dom}/${dir}"

if curl -s --insecure -m2 ${target1}/test.txt | grep "success" > /dev/null ;then
echo ${target1} >> dir.result
break
elif curl -s --insecure -m2 ${target2}/test.txt | grep "success"  > /dev/null;then
echo ${target2} >> dir.result
break
elif  curl -s --insecure -m2 ${target3}/test.txt | grep "success"  > /dev/null; then
echo ${target3} >> dir.result
break
elif  curl -s --insecure -m2 ${target4}/test.txt | grep "success" > /dev/null ; then
echo ${target4} >> dir.result
break
fi
done
done

【问题讨论】:

  • 也许break 2 会有所帮助
  • 放在哪里??在哪一部分??
  • http://example.com:xyz 中冒号后面的正常名称是“端口”,而不是“目录”。
  • 对不起,我弄错了,因为我从过去编写的另一个代码中复制了代码

标签: bash loops if-statement for-loop


【解决方案1】:

您的代码不是最佳的;如果你有一个包含 5 个 'dir' 值的列表,你会检查 5 次 http://${domain}/test.txt 是否存在 - 但如果第一次不存在,那么其他时间也不存在。

您使用dir 表示子目录名称,但您的代码使用http://${dom}:${dir} 而不是更普通的http://${dom}/${dir}。从技术上讲,冒号后面的第一个斜杠是端口号,而不是目录。我假设这是一个错字,冒号应该用斜杠代替。

一般情况下,不要使用反引号;请改用$(…)。也避免大量重复的代码。

我认为你可以将你的脚本压缩成这样:

#!/bin/bash
dirs=( $(cat dir.list) )
file=test.txt

fetch_file()
{
    if curl -s --insecure -m2 "${1:?}/${file}" | grep "success" > /dev/null
    then
        echo "${1}"
        return 0
    else
        return 1
    fi
}

for dom in $(cat domain.list)
do
    for proto in http https
    do
        fetch_file "${proto}://{$dom}" && break
        for dir in "${dirs[@]}"
        do
            fetch_file "${proto}://${dom}/${dir}" && break 2
        done
    done
done > dir.result

如果域列表很大,您可以考虑使用while read dom; do …; done < domain.list 而不是使用$(cat domain.list)。定义变量site="${proto}://${dom}" 然后在fetch_file 的调用中使用它是可行的,甚至可能是明智的。

【讨论】:

  • 非常感谢您的帮助,我对此进行了测试并且效果很好,再次感谢,但我有一个小问题,我已经测试了 1 个域和大约 10000 个目录的脚本:D 需要一个多小时才检查前2个目录是不是正常???应该花那么多时间吗?再次感谢您的帮助
  • 简短的回答是“我不知道”。更长的答案说:我会感到惊讶,因为通常网站会迅速响应请求(通常不到一秒,最多几秒钟)。所以,如果出现性能问题,首先要做的就是在函数中添加时序代码;打印curl 之前和之后的 URL 和日期,可能会将这些输出发送到标准错误 (>&2)。我想知道https 连接是否是导致缓慢的原因?您会很快发现时间安排到位。许多网站对http 和https 的响应都是一样的,但并非所有网站都这样做。
  • 我的简短回答是“我也不知道”:D 但是当我尝试使用 https 命令运行新脚本时只检查 10 目录,我的目标是将工作目录放在列表的末尾,我在不到 3 分钟的时间内得到了结果 :) 这很奇怪,我不是专家,这就是为什么我要为你分享这些信息,先生,你怎么看??
【解决方案2】:

你可以使用这个脚本:

while read dom; do
   while read dir; do
      target1="http://${dom}"
      target2="https://${dom}"
      target3="http://${dom}:${dir}"
      target4="https://${dom}:${dir}"

      if curl -s --insecure -m2 ${target1}/test.txt | grep -q "success"; then
         echo ${target1} >> dir.result
         break 2
      elif curl -s --insecure -m2 ${target2}/test.txt | grep -q "success"; then
         echo ${target2} >> dir.result
         break 2
      elif curl -s --insecure -m2 ${target3}/test.txt | grep -q "success"; then
         echo ${target3} >> dir.result
         break 2
      elif curl -s --insecure -m2 ${target4}/test.txt | grep -q "success"; then
         echo ${target4} >> dir.result
         break 2
      fi
   done < dir.list
done < domain.list

【讨论】:

    猜你喜欢
    • 2011-08-16
    • 2019-05-02
    • 1970-01-01
    • 1970-01-01
    • 2021-10-18
    • 1970-01-01
    • 2020-07-24
    • 2015-01-24
    • 2013-06-22
    相关资源
    最近更新 更多