Crontab and Tmux not playing well together

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












1















So I want my server to run a script which starts several tmux sessions on boot.

This is my crontab:



@reboot . /home/steven/.profile; /home/steven/Scripts/Start.sh 


And this is the content of my Start.sh



#!/bin/bash 

cd ~/Scripts/

echo "Mounting all drives..."
sudo mount -a
echo "Mounting finished."

echo "Starting Wemo Server..."
tmux new -s "wemo" -d
tmux send -t "wemo" $'./start_wemo_server.shn'
if (tmux list-sessions | grep "wemo");
then
echo "Wemo Server Ouimeaux started."
else
echo "Tmux error @ wemo server."
fi

echo "Starting GoDaddy Dynamic DNS Service..."
tmux new -ds "godaddy"
tmux send -t "godaddy" $'./start_godaddy_dyndns.shn'
if (tmux list-sessions | grep "godaddy");
then
echo "GoDaddy Dynamic DNS Service started."
else
echo "Tmux error @ GoDaddy."
fi

echo "Starting Plex..."
sudo service plexmediaserver start
echo "Plex started."

echo "Starting PlexConnect Server..."
tmux new -ds "plex"
tmux send -t "plex" $'./start_plex_connect.shn'

if (tmux list-sessions | grep "plex");
then
echo "PlexConnect Server started."
else
echo "Tmux error @ Plex."
fi

echo "All starting sequences are finished. Quitting..."


If I start this script manually (i.e. ./Scripts/Start.sh), everything works just fine, tmux loads my profile nicely and everything is okay. However if I set the crontab to start this script, tmux doesn't load the profile, .bashrc isn't loaded, I can't even use Up Arrow key to recall previous commands, or Tab to autocomplete.



This is really rather annoying because I use tmux during the day all the time, I can't live with a broken tmux session.



Does anyone have an idea of how this can be fixed or what I've done wrong?



Thank you.










share|improve this question

















  • 1





    Differences in behavior between cron execution and manual execution are usually due to differences in the environment variables during run. Make sure you're sourcing all your own startup files (in particular, /etc/profile, which often sources /etc/bashrc or similar on its own). You may also have to manually set $HOME (this is an important one).

    – Tom Hunt
    Nov 25 '15 at 0:03











  • If you don't source your own dotfiles (.bashrc, .profile, .bash_profile, etc.), then at least set the $PATH environment variable, which could be drastically different than what is getting loaded in your normal shell. This is just as important (if not more-so) than setting $HOME. Additionally, when running scripts via cronjob, it never hurts to include absolute paths. Most of the time, cronjobs do not start in the same directory as the script that is being executed.

    – rubynorails
    Nov 25 '15 at 2:19












  • The script is only starting services, why do that via crontab and not via your systems service manager?

    – Wieland
    Nov 25 '15 at 8:29











  • Read your .profile inside of the script instead of at the cron level.

    – chicks
    Nov 25 '15 at 13:29











  • @rubynorails how do you go about doing that? I'm a bit of a noob at Linux. I thought the . /home/steven/.profile would be the same as sourcing it?

    – Steven X. Han
    Nov 26 '15 at 8:52















1















So I want my server to run a script which starts several tmux sessions on boot.

This is my crontab:



@reboot . /home/steven/.profile; /home/steven/Scripts/Start.sh 


And this is the content of my Start.sh



#!/bin/bash 

cd ~/Scripts/

echo "Mounting all drives..."
sudo mount -a
echo "Mounting finished."

echo "Starting Wemo Server..."
tmux new -s "wemo" -d
tmux send -t "wemo" $'./start_wemo_server.shn'
if (tmux list-sessions | grep "wemo");
then
echo "Wemo Server Ouimeaux started."
else
echo "Tmux error @ wemo server."
fi

echo "Starting GoDaddy Dynamic DNS Service..."
tmux new -ds "godaddy"
tmux send -t "godaddy" $'./start_godaddy_dyndns.shn'
if (tmux list-sessions | grep "godaddy");
then
echo "GoDaddy Dynamic DNS Service started."
else
echo "Tmux error @ GoDaddy."
fi

echo "Starting Plex..."
sudo service plexmediaserver start
echo "Plex started."

echo "Starting PlexConnect Server..."
tmux new -ds "plex"
tmux send -t "plex" $'./start_plex_connect.shn'

if (tmux list-sessions | grep "plex");
then
echo "PlexConnect Server started."
else
echo "Tmux error @ Plex."
fi

echo "All starting sequences are finished. Quitting..."


If I start this script manually (i.e. ./Scripts/Start.sh), everything works just fine, tmux loads my profile nicely and everything is okay. However if I set the crontab to start this script, tmux doesn't load the profile, .bashrc isn't loaded, I can't even use Up Arrow key to recall previous commands, or Tab to autocomplete.



This is really rather annoying because I use tmux during the day all the time, I can't live with a broken tmux session.



Does anyone have an idea of how this can be fixed or what I've done wrong?



Thank you.










share|improve this question

















  • 1





    Differences in behavior between cron execution and manual execution are usually due to differences in the environment variables during run. Make sure you're sourcing all your own startup files (in particular, /etc/profile, which often sources /etc/bashrc or similar on its own). You may also have to manually set $HOME (this is an important one).

    – Tom Hunt
    Nov 25 '15 at 0:03











  • If you don't source your own dotfiles (.bashrc, .profile, .bash_profile, etc.), then at least set the $PATH environment variable, which could be drastically different than what is getting loaded in your normal shell. This is just as important (if not more-so) than setting $HOME. Additionally, when running scripts via cronjob, it never hurts to include absolute paths. Most of the time, cronjobs do not start in the same directory as the script that is being executed.

    – rubynorails
    Nov 25 '15 at 2:19












  • The script is only starting services, why do that via crontab and not via your systems service manager?

    – Wieland
    Nov 25 '15 at 8:29











  • Read your .profile inside of the script instead of at the cron level.

    – chicks
    Nov 25 '15 at 13:29











  • @rubynorails how do you go about doing that? I'm a bit of a noob at Linux. I thought the . /home/steven/.profile would be the same as sourcing it?

    – Steven X. Han
    Nov 26 '15 at 8:52













1












1








1








So I want my server to run a script which starts several tmux sessions on boot.

This is my crontab:



@reboot . /home/steven/.profile; /home/steven/Scripts/Start.sh 


And this is the content of my Start.sh



#!/bin/bash 

cd ~/Scripts/

echo "Mounting all drives..."
sudo mount -a
echo "Mounting finished."

echo "Starting Wemo Server..."
tmux new -s "wemo" -d
tmux send -t "wemo" $'./start_wemo_server.shn'
if (tmux list-sessions | grep "wemo");
then
echo "Wemo Server Ouimeaux started."
else
echo "Tmux error @ wemo server."
fi

echo "Starting GoDaddy Dynamic DNS Service..."
tmux new -ds "godaddy"
tmux send -t "godaddy" $'./start_godaddy_dyndns.shn'
if (tmux list-sessions | grep "godaddy");
then
echo "GoDaddy Dynamic DNS Service started."
else
echo "Tmux error @ GoDaddy."
fi

echo "Starting Plex..."
sudo service plexmediaserver start
echo "Plex started."

echo "Starting PlexConnect Server..."
tmux new -ds "plex"
tmux send -t "plex" $'./start_plex_connect.shn'

if (tmux list-sessions | grep "plex");
then
echo "PlexConnect Server started."
else
echo "Tmux error @ Plex."
fi

echo "All starting sequences are finished. Quitting..."


If I start this script manually (i.e. ./Scripts/Start.sh), everything works just fine, tmux loads my profile nicely and everything is okay. However if I set the crontab to start this script, tmux doesn't load the profile, .bashrc isn't loaded, I can't even use Up Arrow key to recall previous commands, or Tab to autocomplete.



This is really rather annoying because I use tmux during the day all the time, I can't live with a broken tmux session.



Does anyone have an idea of how this can be fixed or what I've done wrong?



Thank you.










share|improve this question














So I want my server to run a script which starts several tmux sessions on boot.

This is my crontab:



@reboot . /home/steven/.profile; /home/steven/Scripts/Start.sh 


And this is the content of my Start.sh



#!/bin/bash 

cd ~/Scripts/

echo "Mounting all drives..."
sudo mount -a
echo "Mounting finished."

echo "Starting Wemo Server..."
tmux new -s "wemo" -d
tmux send -t "wemo" $'./start_wemo_server.shn'
if (tmux list-sessions | grep "wemo");
then
echo "Wemo Server Ouimeaux started."
else
echo "Tmux error @ wemo server."
fi

echo "Starting GoDaddy Dynamic DNS Service..."
tmux new -ds "godaddy"
tmux send -t "godaddy" $'./start_godaddy_dyndns.shn'
if (tmux list-sessions | grep "godaddy");
then
echo "GoDaddy Dynamic DNS Service started."
else
echo "Tmux error @ GoDaddy."
fi

echo "Starting Plex..."
sudo service plexmediaserver start
echo "Plex started."

echo "Starting PlexConnect Server..."
tmux new -ds "plex"
tmux send -t "plex" $'./start_plex_connect.shn'

if (tmux list-sessions | grep "plex");
then
echo "PlexConnect Server started."
else
echo "Tmux error @ Plex."
fi

echo "All starting sequences are finished. Quitting..."


If I start this script manually (i.e. ./Scripts/Start.sh), everything works just fine, tmux loads my profile nicely and everything is okay. However if I set the crontab to start this script, tmux doesn't load the profile, .bashrc isn't loaded, I can't even use Up Arrow key to recall previous commands, or Tab to autocomplete.



This is really rather annoying because I use tmux during the day all the time, I can't live with a broken tmux session.



Does anyone have an idea of how this can be fixed or what I've done wrong?



Thank you.







linux bash scripting cron tmux






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 24 '15 at 23:59









Steven X. HanSteven X. Han

62




62







  • 1





    Differences in behavior between cron execution and manual execution are usually due to differences in the environment variables during run. Make sure you're sourcing all your own startup files (in particular, /etc/profile, which often sources /etc/bashrc or similar on its own). You may also have to manually set $HOME (this is an important one).

    – Tom Hunt
    Nov 25 '15 at 0:03











  • If you don't source your own dotfiles (.bashrc, .profile, .bash_profile, etc.), then at least set the $PATH environment variable, which could be drastically different than what is getting loaded in your normal shell. This is just as important (if not more-so) than setting $HOME. Additionally, when running scripts via cronjob, it never hurts to include absolute paths. Most of the time, cronjobs do not start in the same directory as the script that is being executed.

    – rubynorails
    Nov 25 '15 at 2:19












  • The script is only starting services, why do that via crontab and not via your systems service manager?

    – Wieland
    Nov 25 '15 at 8:29











  • Read your .profile inside of the script instead of at the cron level.

    – chicks
    Nov 25 '15 at 13:29











  • @rubynorails how do you go about doing that? I'm a bit of a noob at Linux. I thought the . /home/steven/.profile would be the same as sourcing it?

    – Steven X. Han
    Nov 26 '15 at 8:52












  • 1





    Differences in behavior between cron execution and manual execution are usually due to differences in the environment variables during run. Make sure you're sourcing all your own startup files (in particular, /etc/profile, which often sources /etc/bashrc or similar on its own). You may also have to manually set $HOME (this is an important one).

    – Tom Hunt
    Nov 25 '15 at 0:03











  • If you don't source your own dotfiles (.bashrc, .profile, .bash_profile, etc.), then at least set the $PATH environment variable, which could be drastically different than what is getting loaded in your normal shell. This is just as important (if not more-so) than setting $HOME. Additionally, when running scripts via cronjob, it never hurts to include absolute paths. Most of the time, cronjobs do not start in the same directory as the script that is being executed.

    – rubynorails
    Nov 25 '15 at 2:19












  • The script is only starting services, why do that via crontab and not via your systems service manager?

    – Wieland
    Nov 25 '15 at 8:29











  • Read your .profile inside of the script instead of at the cron level.

    – chicks
    Nov 25 '15 at 13:29











  • @rubynorails how do you go about doing that? I'm a bit of a noob at Linux. I thought the . /home/steven/.profile would be the same as sourcing it?

    – Steven X. Han
    Nov 26 '15 at 8:52







1




1





Differences in behavior between cron execution and manual execution are usually due to differences in the environment variables during run. Make sure you're sourcing all your own startup files (in particular, /etc/profile, which often sources /etc/bashrc or similar on its own). You may also have to manually set $HOME (this is an important one).

– Tom Hunt
Nov 25 '15 at 0:03





Differences in behavior between cron execution and manual execution are usually due to differences in the environment variables during run. Make sure you're sourcing all your own startup files (in particular, /etc/profile, which often sources /etc/bashrc or similar on its own). You may also have to manually set $HOME (this is an important one).

– Tom Hunt
Nov 25 '15 at 0:03













If you don't source your own dotfiles (.bashrc, .profile, .bash_profile, etc.), then at least set the $PATH environment variable, which could be drastically different than what is getting loaded in your normal shell. This is just as important (if not more-so) than setting $HOME. Additionally, when running scripts via cronjob, it never hurts to include absolute paths. Most of the time, cronjobs do not start in the same directory as the script that is being executed.

– rubynorails
Nov 25 '15 at 2:19






If you don't source your own dotfiles (.bashrc, .profile, .bash_profile, etc.), then at least set the $PATH environment variable, which could be drastically different than what is getting loaded in your normal shell. This is just as important (if not more-so) than setting $HOME. Additionally, when running scripts via cronjob, it never hurts to include absolute paths. Most of the time, cronjobs do not start in the same directory as the script that is being executed.

– rubynorails
Nov 25 '15 at 2:19














The script is only starting services, why do that via crontab and not via your systems service manager?

– Wieland
Nov 25 '15 at 8:29





The script is only starting services, why do that via crontab and not via your systems service manager?

– Wieland
Nov 25 '15 at 8:29













Read your .profile inside of the script instead of at the cron level.

– chicks
Nov 25 '15 at 13:29





Read your .profile inside of the script instead of at the cron level.

– chicks
Nov 25 '15 at 13:29













@rubynorails how do you go about doing that? I'm a bit of a noob at Linux. I thought the . /home/steven/.profile would be the same as sourcing it?

– Steven X. Han
Nov 26 '15 at 8:52





@rubynorails how do you go about doing that? I'm a bit of a noob at Linux. I thought the . /home/steven/.profile would be the same as sourcing it?

– Steven X. Han
Nov 26 '15 at 8:52










1 Answer
1






active

oldest

votes


















0














Wherever your personal settings are loaded, depending on OS and preference, you need to source that file in the script so that it functions as it would if you were running it yourself in the terminal.



source or . is a command that functions sort of like import in other scripting/programming languages. Also note that if you use . instead of source, there should be a space between the . and the path to the profile you are sourcing:



. /home/username/.profile


At the beginning of your script, after #!/bin/bash, simply add source /home/yourusername/.profile (or .bashrc or whatever you are using to load your settings).



Double-check the permissions/ownership of the file, and make sure it's running in your personal crontab and not root's crontab, which would mess everything up if you were trying to run it as a normal user.



Also, like I said in my comment, it never hurts to include absolute paths in scripts that are being executed via cron. I believe you have multiple instances referencing ~/something or ./somescript. For instance, instead of cd ~/Scripts, use cd /home/username/Scripts, so that there can be no mistake of where this directory is located.



This is the point of source-ing your .profile, because that is normally where the $HOME variable (~) gets set. The way to avoid any discrepancy whatsoever, is just include absolutely paths to directories and scripts when you know jobs will be executed via cron.






share|improve this answer























  • So I've done this: #!/bin/bash source ./home/steven/.profile echo "Mounting all drives..." sudo mount -a echo "Mounting finished." echo "Starting Wemo Server..." tmux new -s "wemo" -d ... but the tmux sessions still aren't initialised with my .profile loaded

    – Steven X. Han
    Nov 27 '15 at 10:18











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',
autoActivateHeartbeat: false,
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%2f245289%2fcrontab-and-tmux-not-playing-well-together%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









0














Wherever your personal settings are loaded, depending on OS and preference, you need to source that file in the script so that it functions as it would if you were running it yourself in the terminal.



source or . is a command that functions sort of like import in other scripting/programming languages. Also note that if you use . instead of source, there should be a space between the . and the path to the profile you are sourcing:



. /home/username/.profile


At the beginning of your script, after #!/bin/bash, simply add source /home/yourusername/.profile (or .bashrc or whatever you are using to load your settings).



Double-check the permissions/ownership of the file, and make sure it's running in your personal crontab and not root's crontab, which would mess everything up if you were trying to run it as a normal user.



Also, like I said in my comment, it never hurts to include absolute paths in scripts that are being executed via cron. I believe you have multiple instances referencing ~/something or ./somescript. For instance, instead of cd ~/Scripts, use cd /home/username/Scripts, so that there can be no mistake of where this directory is located.



This is the point of source-ing your .profile, because that is normally where the $HOME variable (~) gets set. The way to avoid any discrepancy whatsoever, is just include absolutely paths to directories and scripts when you know jobs will be executed via cron.






share|improve this answer























  • So I've done this: #!/bin/bash source ./home/steven/.profile echo "Mounting all drives..." sudo mount -a echo "Mounting finished." echo "Starting Wemo Server..." tmux new -s "wemo" -d ... but the tmux sessions still aren't initialised with my .profile loaded

    – Steven X. Han
    Nov 27 '15 at 10:18
















0














Wherever your personal settings are loaded, depending on OS and preference, you need to source that file in the script so that it functions as it would if you were running it yourself in the terminal.



source or . is a command that functions sort of like import in other scripting/programming languages. Also note that if you use . instead of source, there should be a space between the . and the path to the profile you are sourcing:



. /home/username/.profile


At the beginning of your script, after #!/bin/bash, simply add source /home/yourusername/.profile (or .bashrc or whatever you are using to load your settings).



Double-check the permissions/ownership of the file, and make sure it's running in your personal crontab and not root's crontab, which would mess everything up if you were trying to run it as a normal user.



Also, like I said in my comment, it never hurts to include absolute paths in scripts that are being executed via cron. I believe you have multiple instances referencing ~/something or ./somescript. For instance, instead of cd ~/Scripts, use cd /home/username/Scripts, so that there can be no mistake of where this directory is located.



This is the point of source-ing your .profile, because that is normally where the $HOME variable (~) gets set. The way to avoid any discrepancy whatsoever, is just include absolutely paths to directories and scripts when you know jobs will be executed via cron.






share|improve this answer























  • So I've done this: #!/bin/bash source ./home/steven/.profile echo "Mounting all drives..." sudo mount -a echo "Mounting finished." echo "Starting Wemo Server..." tmux new -s "wemo" -d ... but the tmux sessions still aren't initialised with my .profile loaded

    – Steven X. Han
    Nov 27 '15 at 10:18














0












0








0







Wherever your personal settings are loaded, depending on OS and preference, you need to source that file in the script so that it functions as it would if you were running it yourself in the terminal.



source or . is a command that functions sort of like import in other scripting/programming languages. Also note that if you use . instead of source, there should be a space between the . and the path to the profile you are sourcing:



. /home/username/.profile


At the beginning of your script, after #!/bin/bash, simply add source /home/yourusername/.profile (or .bashrc or whatever you are using to load your settings).



Double-check the permissions/ownership of the file, and make sure it's running in your personal crontab and not root's crontab, which would mess everything up if you were trying to run it as a normal user.



Also, like I said in my comment, it never hurts to include absolute paths in scripts that are being executed via cron. I believe you have multiple instances referencing ~/something or ./somescript. For instance, instead of cd ~/Scripts, use cd /home/username/Scripts, so that there can be no mistake of where this directory is located.



This is the point of source-ing your .profile, because that is normally where the $HOME variable (~) gets set. The way to avoid any discrepancy whatsoever, is just include absolutely paths to directories and scripts when you know jobs will be executed via cron.






share|improve this answer













Wherever your personal settings are loaded, depending on OS and preference, you need to source that file in the script so that it functions as it would if you were running it yourself in the terminal.



source or . is a command that functions sort of like import in other scripting/programming languages. Also note that if you use . instead of source, there should be a space between the . and the path to the profile you are sourcing:



. /home/username/.profile


At the beginning of your script, after #!/bin/bash, simply add source /home/yourusername/.profile (or .bashrc or whatever you are using to load your settings).



Double-check the permissions/ownership of the file, and make sure it's running in your personal crontab and not root's crontab, which would mess everything up if you were trying to run it as a normal user.



Also, like I said in my comment, it never hurts to include absolute paths in scripts that are being executed via cron. I believe you have multiple instances referencing ~/something or ./somescript. For instance, instead of cd ~/Scripts, use cd /home/username/Scripts, so that there can be no mistake of where this directory is located.



This is the point of source-ing your .profile, because that is normally where the $HOME variable (~) gets set. The way to avoid any discrepancy whatsoever, is just include absolutely paths to directories and scripts when you know jobs will be executed via cron.







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 26 '15 at 13:58









rubynorailsrubynorails

1,282516




1,282516












  • So I've done this: #!/bin/bash source ./home/steven/.profile echo "Mounting all drives..." sudo mount -a echo "Mounting finished." echo "Starting Wemo Server..." tmux new -s "wemo" -d ... but the tmux sessions still aren't initialised with my .profile loaded

    – Steven X. Han
    Nov 27 '15 at 10:18


















  • So I've done this: #!/bin/bash source ./home/steven/.profile echo "Mounting all drives..." sudo mount -a echo "Mounting finished." echo "Starting Wemo Server..." tmux new -s "wemo" -d ... but the tmux sessions still aren't initialised with my .profile loaded

    – Steven X. Han
    Nov 27 '15 at 10:18

















So I've done this: #!/bin/bash source ./home/steven/.profile echo "Mounting all drives..." sudo mount -a echo "Mounting finished." echo "Starting Wemo Server..." tmux new -s "wemo" -d ... but the tmux sessions still aren't initialised with my .profile loaded

– Steven X. Han
Nov 27 '15 at 10:18






So I've done this: #!/bin/bash source ./home/steven/.profile echo "Mounting all drives..." sudo mount -a echo "Mounting finished." echo "Starting Wemo Server..." tmux new -s "wemo" -d ... but the tmux sessions still aren't initialised with my .profile loaded

– Steven X. Han
Nov 27 '15 at 10:18


















draft saved

draft discarded
















































Thanks for contributing an answer to Unix & Linux Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f245289%2fcrontab-and-tmux-not-playing-well-together%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