bash regular expression point “.” character not matching

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
0
down vote

favorite












The string I'm trying to match is an ip address and I've seens quite some examples on the web. However it appears that I'm missing something which may or may not have to do with the differences between regexp conventions. (pcre, ere, ??)



To break it down to the point I'm missing here's the partial ip address that I'm trying to get matched:



ip="255.255."


This is a regular expression that tries to match above ip:



^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?.)2


It's bash so I've got this to compare:



[[ $ip =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?.)2 ]] && echo "ok"


Alas, it doesn't match.



As far as I know, I'm allowed to escape the . because I want it to match a point character, not just any character. (what . stands for in regexp to the best of my knowledge.)



This is what happens when I remove the escape before the point to illustrate above statement:



# ip="255.255."
# [[ $ip =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?.)2 ]] && echo "ok"
ok
# ip="255X255Y"
# [[ $ip =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9] [0-9]?.)2 ]] && echo "ok"
ok


That's not correct to match (partial) ip in this case.



Why does it not match this:



# ip="255.255."
# [[ $ip =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?.)2 ]] && echo "ok" || echo "nope"
nope


There are two groups and each of them is "255." and that part matches just fine like this:



# ip="255."
# [[ $ip =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?.) ]] && echo "ok" || echo "nope"
ok


EDIT: some extra info that possibly solves my issue:



just noticed the following:



# ip="172.15.11.10"
# [[ $ip =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?.)2 ]] && echo "ok" || echo "nope"
ok
# ip="172.15."
# [[ $ip =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?.)2 ]] && echo "ok" || echo "nope"
ok


And when the following grouping is made:



# [[ $ip =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?.)2 ]] && echo "ok" || echo "nope"
nope
# [[ $ip =~ ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).)2 ]] && echo "ok" || echo "nope"
ok


So grouping the "number" part in front of the seperator "point" solves the issue?



# ip="255.255."
# [[ $ip =~ ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).)2 ]] && echo "ok" || echo "nope"
ok


I'm inclined to think this solves it however I do not yet understand why.



EDIT: the full regexp for the ip address is this here:



^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).)3(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)


This is the same mentioned by Jeff in below answer.










share|improve this question



























    up vote
    0
    down vote

    favorite












    The string I'm trying to match is an ip address and I've seens quite some examples on the web. However it appears that I'm missing something which may or may not have to do with the differences between regexp conventions. (pcre, ere, ??)



    To break it down to the point I'm missing here's the partial ip address that I'm trying to get matched:



    ip="255.255."


    This is a regular expression that tries to match above ip:



    ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?.)2


    It's bash so I've got this to compare:



    [[ $ip =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?.)2 ]] && echo "ok"


    Alas, it doesn't match.



    As far as I know, I'm allowed to escape the . because I want it to match a point character, not just any character. (what . stands for in regexp to the best of my knowledge.)



    This is what happens when I remove the escape before the point to illustrate above statement:



    # ip="255.255."
    # [[ $ip =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?.)2 ]] && echo "ok"
    ok
    # ip="255X255Y"
    # [[ $ip =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9] [0-9]?.)2 ]] && echo "ok"
    ok


    That's not correct to match (partial) ip in this case.



    Why does it not match this:



    # ip="255.255."
    # [[ $ip =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?.)2 ]] && echo "ok" || echo "nope"
    nope


    There are two groups and each of them is "255." and that part matches just fine like this:



    # ip="255."
    # [[ $ip =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?.) ]] && echo "ok" || echo "nope"
    ok


    EDIT: some extra info that possibly solves my issue:



    just noticed the following:



    # ip="172.15.11.10"
    # [[ $ip =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?.)2 ]] && echo "ok" || echo "nope"
    ok
    # ip="172.15."
    # [[ $ip =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?.)2 ]] && echo "ok" || echo "nope"
    ok


    And when the following grouping is made:



    # [[ $ip =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?.)2 ]] && echo "ok" || echo "nope"
    nope
    # [[ $ip =~ ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).)2 ]] && echo "ok" || echo "nope"
    ok


    So grouping the "number" part in front of the seperator "point" solves the issue?



    # ip="255.255."
    # [[ $ip =~ ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).)2 ]] && echo "ok" || echo "nope"
    ok


    I'm inclined to think this solves it however I do not yet understand why.



    EDIT: the full regexp for the ip address is this here:



    ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).)3(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)


    This is the same mentioned by Jeff in below answer.










    share|improve this question

























      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      The string I'm trying to match is an ip address and I've seens quite some examples on the web. However it appears that I'm missing something which may or may not have to do with the differences between regexp conventions. (pcre, ere, ??)



      To break it down to the point I'm missing here's the partial ip address that I'm trying to get matched:



      ip="255.255."


      This is a regular expression that tries to match above ip:



      ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?.)2


      It's bash so I've got this to compare:



      [[ $ip =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?.)2 ]] && echo "ok"


      Alas, it doesn't match.



      As far as I know, I'm allowed to escape the . because I want it to match a point character, not just any character. (what . stands for in regexp to the best of my knowledge.)



      This is what happens when I remove the escape before the point to illustrate above statement:



      # ip="255.255."
      # [[ $ip =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?.)2 ]] && echo "ok"
      ok
      # ip="255X255Y"
      # [[ $ip =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9] [0-9]?.)2 ]] && echo "ok"
      ok


      That's not correct to match (partial) ip in this case.



      Why does it not match this:



      # ip="255.255."
      # [[ $ip =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?.)2 ]] && echo "ok" || echo "nope"
      nope


      There are two groups and each of them is "255." and that part matches just fine like this:



      # ip="255."
      # [[ $ip =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?.) ]] && echo "ok" || echo "nope"
      ok


      EDIT: some extra info that possibly solves my issue:



      just noticed the following:



      # ip="172.15.11.10"
      # [[ $ip =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?.)2 ]] && echo "ok" || echo "nope"
      ok
      # ip="172.15."
      # [[ $ip =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?.)2 ]] && echo "ok" || echo "nope"
      ok


      And when the following grouping is made:



      # [[ $ip =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?.)2 ]] && echo "ok" || echo "nope"
      nope
      # [[ $ip =~ ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).)2 ]] && echo "ok" || echo "nope"
      ok


      So grouping the "number" part in front of the seperator "point" solves the issue?



      # ip="255.255."
      # [[ $ip =~ ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).)2 ]] && echo "ok" || echo "nope"
      ok


      I'm inclined to think this solves it however I do not yet understand why.



      EDIT: the full regexp for the ip address is this here:



      ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).)3(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)


      This is the same mentioned by Jeff in below answer.










      share|improve this question















      The string I'm trying to match is an ip address and I've seens quite some examples on the web. However it appears that I'm missing something which may or may not have to do with the differences between regexp conventions. (pcre, ere, ??)



      To break it down to the point I'm missing here's the partial ip address that I'm trying to get matched:



      ip="255.255."


      This is a regular expression that tries to match above ip:



      ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?.)2


      It's bash so I've got this to compare:



      [[ $ip =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?.)2 ]] && echo "ok"


      Alas, it doesn't match.



      As far as I know, I'm allowed to escape the . because I want it to match a point character, not just any character. (what . stands for in regexp to the best of my knowledge.)



      This is what happens when I remove the escape before the point to illustrate above statement:



      # ip="255.255."
      # [[ $ip =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?.)2 ]] && echo "ok"
      ok
      # ip="255X255Y"
      # [[ $ip =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9] [0-9]?.)2 ]] && echo "ok"
      ok


      That's not correct to match (partial) ip in this case.



      Why does it not match this:



      # ip="255.255."
      # [[ $ip =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?.)2 ]] && echo "ok" || echo "nope"
      nope


      There are two groups and each of them is "255." and that part matches just fine like this:



      # ip="255."
      # [[ $ip =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?.) ]] && echo "ok" || echo "nope"
      ok


      EDIT: some extra info that possibly solves my issue:



      just noticed the following:



      # ip="172.15.11.10"
      # [[ $ip =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?.)2 ]] && echo "ok" || echo "nope"
      ok
      # ip="172.15."
      # [[ $ip =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?.)2 ]] && echo "ok" || echo "nope"
      ok


      And when the following grouping is made:



      # [[ $ip =~ ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?.)2 ]] && echo "ok" || echo "nope"
      nope
      # [[ $ip =~ ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).)2 ]] && echo "ok" || echo "nope"
      ok


      So grouping the "number" part in front of the seperator "point" solves the issue?



      # ip="255.255."
      # [[ $ip =~ ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).)2 ]] && echo "ok" || echo "nope"
      ok


      I'm inclined to think this solves it however I do not yet understand why.



      EDIT: the full regexp for the ip address is this here:



      ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).)3(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)


      This is the same mentioned by Jeff in below answer.







      bash regular-expression






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 21 at 15:05

























      asked Nov 21 at 14:26









      lievendp

      416




      416




















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          3
          down vote



          accepted










          The parenthesis were in the wrong place.



          In the failing regex, you had grouped the octet's possibilities together with alternations:



          ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?.)


          ... which would match the beginning of line ^ followed by:




          • 25[0-5] or


          • 2[0-4][0-9] or

          • [01]?[0-9][0-9]?.

          Notice how the period is part of the 3rd possible alternation. That forces the regex to match the initial 255, leaving the following period unmatched.



          You want the octet and the period to be repeated, so group the regex like this:



          ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).)2


          or like this:



          ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).)3(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$


          ... so that there are four octets.



          That forces the IP address to appear by itself on a line. If you don't care where in the line the IP address shows up, then drop the leading (^) and trailing ($) anchors.



          On Linux, for a visual aid in testing, you could use grep --color=always -E ..., for instance:



          $ ip=jeff-255.255.255.255-foo
          $ echo "$ip" | grep --color=always -E '((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).)3(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)'


          jeff-255.255.255.255-foo


          ... where the 255.255.255.255 shows up in color.






          share|improve this answer






















          • thanks for the explanation, so the grouping was wrong and this made "." become a part of the last possible alteration from the list. it works great now. Also thanks for the coloring option, I never looked at that before. :-)
            – lievendp
            Nov 21 at 15:07











          Your Answer








          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "106"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader:
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          ,
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













           

          draft saved


          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f483221%2fbash-regular-expression-point-character-not-matching%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          3
          down vote



          accepted










          The parenthesis were in the wrong place.



          In the failing regex, you had grouped the octet's possibilities together with alternations:



          ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?.)


          ... which would match the beginning of line ^ followed by:




          • 25[0-5] or


          • 2[0-4][0-9] or

          • [01]?[0-9][0-9]?.

          Notice how the period is part of the 3rd possible alternation. That forces the regex to match the initial 255, leaving the following period unmatched.



          You want the octet and the period to be repeated, so group the regex like this:



          ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).)2


          or like this:



          ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).)3(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$


          ... so that there are four octets.



          That forces the IP address to appear by itself on a line. If you don't care where in the line the IP address shows up, then drop the leading (^) and trailing ($) anchors.



          On Linux, for a visual aid in testing, you could use grep --color=always -E ..., for instance:



          $ ip=jeff-255.255.255.255-foo
          $ echo "$ip" | grep --color=always -E '((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).)3(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)'


          jeff-255.255.255.255-foo


          ... where the 255.255.255.255 shows up in color.






          share|improve this answer






















          • thanks for the explanation, so the grouping was wrong and this made "." become a part of the last possible alteration from the list. it works great now. Also thanks for the coloring option, I never looked at that before. :-)
            – lievendp
            Nov 21 at 15:07















          up vote
          3
          down vote



          accepted










          The parenthesis were in the wrong place.



          In the failing regex, you had grouped the octet's possibilities together with alternations:



          ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?.)


          ... which would match the beginning of line ^ followed by:




          • 25[0-5] or


          • 2[0-4][0-9] or

          • [01]?[0-9][0-9]?.

          Notice how the period is part of the 3rd possible alternation. That forces the regex to match the initial 255, leaving the following period unmatched.



          You want the octet and the period to be repeated, so group the regex like this:



          ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).)2


          or like this:



          ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).)3(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$


          ... so that there are four octets.



          That forces the IP address to appear by itself on a line. If you don't care where in the line the IP address shows up, then drop the leading (^) and trailing ($) anchors.



          On Linux, for a visual aid in testing, you could use grep --color=always -E ..., for instance:



          $ ip=jeff-255.255.255.255-foo
          $ echo "$ip" | grep --color=always -E '((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).)3(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)'


          jeff-255.255.255.255-foo


          ... where the 255.255.255.255 shows up in color.






          share|improve this answer






















          • thanks for the explanation, so the grouping was wrong and this made "." become a part of the last possible alteration from the list. it works great now. Also thanks for the coloring option, I never looked at that before. :-)
            – lievendp
            Nov 21 at 15:07













          up vote
          3
          down vote



          accepted







          up vote
          3
          down vote



          accepted






          The parenthesis were in the wrong place.



          In the failing regex, you had grouped the octet's possibilities together with alternations:



          ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?.)


          ... which would match the beginning of line ^ followed by:




          • 25[0-5] or


          • 2[0-4][0-9] or

          • [01]?[0-9][0-9]?.

          Notice how the period is part of the 3rd possible alternation. That forces the regex to match the initial 255, leaving the following period unmatched.



          You want the octet and the period to be repeated, so group the regex like this:



          ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).)2


          or like this:



          ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).)3(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$


          ... so that there are four octets.



          That forces the IP address to appear by itself on a line. If you don't care where in the line the IP address shows up, then drop the leading (^) and trailing ($) anchors.



          On Linux, for a visual aid in testing, you could use grep --color=always -E ..., for instance:



          $ ip=jeff-255.255.255.255-foo
          $ echo "$ip" | grep --color=always -E '((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).)3(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)'


          jeff-255.255.255.255-foo


          ... where the 255.255.255.255 shows up in color.






          share|improve this answer














          The parenthesis were in the wrong place.



          In the failing regex, you had grouped the octet's possibilities together with alternations:



          ^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?.)


          ... which would match the beginning of line ^ followed by:




          • 25[0-5] or


          • 2[0-4][0-9] or

          • [01]?[0-9][0-9]?.

          Notice how the period is part of the 3rd possible alternation. That forces the regex to match the initial 255, leaving the following period unmatched.



          You want the octet and the period to be repeated, so group the regex like this:



          ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).)2


          or like this:



          ^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).)3(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$


          ... so that there are four octets.



          That forces the IP address to appear by itself on a line. If you don't care where in the line the IP address shows up, then drop the leading (^) and trailing ($) anchors.



          On Linux, for a visual aid in testing, you could use grep --color=always -E ..., for instance:



          $ ip=jeff-255.255.255.255-foo
          $ echo "$ip" | grep --color=always -E '((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).)3(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)'


          jeff-255.255.255.255-foo


          ... where the 255.255.255.255 shows up in color.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 24 at 4:39

























          answered Nov 21 at 14:45









          Jeff Schaller

          36.6k1052120




          36.6k1052120











          • thanks for the explanation, so the grouping was wrong and this made "." become a part of the last possible alteration from the list. it works great now. Also thanks for the coloring option, I never looked at that before. :-)
            – lievendp
            Nov 21 at 15:07

















          • thanks for the explanation, so the grouping was wrong and this made "." become a part of the last possible alteration from the list. it works great now. Also thanks for the coloring option, I never looked at that before. :-)
            – lievendp
            Nov 21 at 15:07
















          thanks for the explanation, so the grouping was wrong and this made "." become a part of the last possible alteration from the list. it works great now. Also thanks for the coloring option, I never looked at that before. :-)
          – lievendp
          Nov 21 at 15:07





          thanks for the explanation, so the grouping was wrong and this made "." become a part of the last possible alteration from the list. it works great now. Also thanks for the coloring option, I never looked at that before. :-)
          – lievendp
          Nov 21 at 15:07


















           

          draft saved


          draft discarded















































           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f483221%2fbash-regular-expression-point-character-not-matching%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown






          Popular posts from this blog

          How to check contact read email or not when send email to Individual?

          Bahrain

          Postfix configuration issue with fips on centos 7; mailgun relay