if-up.d launches two instances of a single script
Case:
On our Ubuntu Xenial(16.04) station I host a bot written in Python that connects to our IRC server that's set to launch in /etc/network/if-up.d/
Our bot was connecting twice though the script is set to only run one instance and if its username is taken it must close the current connection and reconnect under the next username.
Troubleshooting:
I used ps aux | grep bot_name.py$ to determine the issue was not at the script level, but for some reason two instances of the script were being run when Ubuntu connected to the internet.
I've created a workaround on the script level that checks how many instances of the script are running locally and if it's any number besides one, it will close the script.
Question:
What would be some reasons if-up.d/might launch two instances of a single script stored in its directory?
if-up.d/Script:
The script in if-up.d/ is a sh script that wraps the call to python so it waits past the timeout period for irc then connects:
sleep 269
sh -c "python /dir/to/bot.py >> /dir/to/log" & disown
Additional Sources:
So far, I've seen the issue mirrored here in a different context where someone used a python script to send emails and the recipients received multiple emails due to multiple instances of their script launching.
I was also able to find this question for 16.04 on Server Fault where someone experienced a similar issue and the answer listed suggested it might be running twice because there's one instance launched for IPv4 and IPv6, though I'm not sure if this is actually the root cause or how to specify you'd only want to use IPv4 and forego the IPv6 call if that was the case.
Between our 3 cases, Ubuntu 16.04 seems to be the common thread which makes me wonder if this is a bug.
16.04 networking network-manager
add a comment |
Case:
On our Ubuntu Xenial(16.04) station I host a bot written in Python that connects to our IRC server that's set to launch in /etc/network/if-up.d/
Our bot was connecting twice though the script is set to only run one instance and if its username is taken it must close the current connection and reconnect under the next username.
Troubleshooting:
I used ps aux | grep bot_name.py$ to determine the issue was not at the script level, but for some reason two instances of the script were being run when Ubuntu connected to the internet.
I've created a workaround on the script level that checks how many instances of the script are running locally and if it's any number besides one, it will close the script.
Question:
What would be some reasons if-up.d/might launch two instances of a single script stored in its directory?
if-up.d/Script:
The script in if-up.d/ is a sh script that wraps the call to python so it waits past the timeout period for irc then connects:
sleep 269
sh -c "python /dir/to/bot.py >> /dir/to/log" & disown
Additional Sources:
So far, I've seen the issue mirrored here in a different context where someone used a python script to send emails and the recipients received multiple emails due to multiple instances of their script launching.
I was also able to find this question for 16.04 on Server Fault where someone experienced a similar issue and the answer listed suggested it might be running twice because there's one instance launched for IPv4 and IPv6, though I'm not sure if this is actually the root cause or how to specify you'd only want to use IPv4 and forego the IPv6 call if that was the case.
Between our 3 cases, Ubuntu 16.04 seems to be the common thread which makes me wonder if this is a bug.
16.04 networking network-manager
add a comment |
Case:
On our Ubuntu Xenial(16.04) station I host a bot written in Python that connects to our IRC server that's set to launch in /etc/network/if-up.d/
Our bot was connecting twice though the script is set to only run one instance and if its username is taken it must close the current connection and reconnect under the next username.
Troubleshooting:
I used ps aux | grep bot_name.py$ to determine the issue was not at the script level, but for some reason two instances of the script were being run when Ubuntu connected to the internet.
I've created a workaround on the script level that checks how many instances of the script are running locally and if it's any number besides one, it will close the script.
Question:
What would be some reasons if-up.d/might launch two instances of a single script stored in its directory?
if-up.d/Script:
The script in if-up.d/ is a sh script that wraps the call to python so it waits past the timeout period for irc then connects:
sleep 269
sh -c "python /dir/to/bot.py >> /dir/to/log" & disown
Additional Sources:
So far, I've seen the issue mirrored here in a different context where someone used a python script to send emails and the recipients received multiple emails due to multiple instances of their script launching.
I was also able to find this question for 16.04 on Server Fault where someone experienced a similar issue and the answer listed suggested it might be running twice because there's one instance launched for IPv4 and IPv6, though I'm not sure if this is actually the root cause or how to specify you'd only want to use IPv4 and forego the IPv6 call if that was the case.
Between our 3 cases, Ubuntu 16.04 seems to be the common thread which makes me wonder if this is a bug.
16.04 networking network-manager
Case:
On our Ubuntu Xenial(16.04) station I host a bot written in Python that connects to our IRC server that's set to launch in /etc/network/if-up.d/
Our bot was connecting twice though the script is set to only run one instance and if its username is taken it must close the current connection and reconnect under the next username.
Troubleshooting:
I used ps aux | grep bot_name.py$ to determine the issue was not at the script level, but for some reason two instances of the script were being run when Ubuntu connected to the internet.
I've created a workaround on the script level that checks how many instances of the script are running locally and if it's any number besides one, it will close the script.
Question:
What would be some reasons if-up.d/might launch two instances of a single script stored in its directory?
if-up.d/Script:
The script in if-up.d/ is a sh script that wraps the call to python so it waits past the timeout period for irc then connects:
sleep 269
sh -c "python /dir/to/bot.py >> /dir/to/log" & disown
Additional Sources:
So far, I've seen the issue mirrored here in a different context where someone used a python script to send emails and the recipients received multiple emails due to multiple instances of their script launching.
I was also able to find this question for 16.04 on Server Fault where someone experienced a similar issue and the answer listed suggested it might be running twice because there's one instance launched for IPv4 and IPv6, though I'm not sure if this is actually the root cause or how to specify you'd only want to use IPv4 and forego the IPv6 call if that was the case.
Between our 3 cases, Ubuntu 16.04 seems to be the common thread which makes me wonder if this is a bug.
16.04 networking network-manager
16.04 networking network-manager
edited Dec 5 at 21:55
asked Dec 5 at 21:15
saniboy
164
164
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
Looking more into 16.04 if-up.d/, I found a similar question for someone running Debian 7.3 and found the answer. It is not a bug, and the issue I experienced is explained here in @Søren Løvborg's answer:
In general, ifup / ifdown does not guarantee that your script only runs once. Thus your script has to be idempotent; that is, contain its own logic not to establish a tunnel that already exists. The best way, of course, is to start the script by actually checking if the tunnel is already there:
# Exit if network device "tun0" exists.
ip link show dev tun0 >/dev/null 2>&1 && exit 0
Additionally, the scripts in if-up.d etc. run for every interface that is brought up. As Jeff correctly observes, the if-*.d scripts receive no arguments specifying e.g. which interface is coming up.
Instead, per the interfaces(5) man page:
There exists for each of the above mentioned options a directory
/etc/network/if-<option>.d/ [...]
All of these commands have access to the following environment vari‐
ables.
IFACE physical name of the interface being processed
LOGICAL
logical name of the interface being processed
[... and more ...]
The solution is to start the script with a check for the correct IFACE value, e.g.:
# Exit if we're not starting "eth0".
[ "$IFACE" = 'eth0' ] || exit 0
Otherwise, the script will run for every network device, including lo, at which point it may be too early to establish a tunnel.
That said, my issue was it was executing the script for the lo interface in addition to my eth0 connection. I took one of the steps which was to program your script with the logic to not run more than once, but to only run it once without adjusting the code just specify the interface to be used
before execution.
If I wanted to go back and solve this on the sh level, I'd simply need to update my script with this line since the interface I want to use is my Ethernet connection
[ "$IFACE" = 'eth0' ] || exit 0
sleep 269
sh -c "python /dir/to/bot.py >> /dir/to/log" & disown
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "89"
};
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: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2faskubuntu.com%2fquestions%2f1098775%2fif-up-d-launches-two-instances-of-a-single-script%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
Looking more into 16.04 if-up.d/, I found a similar question for someone running Debian 7.3 and found the answer. It is not a bug, and the issue I experienced is explained here in @Søren Løvborg's answer:
In general, ifup / ifdown does not guarantee that your script only runs once. Thus your script has to be idempotent; that is, contain its own logic not to establish a tunnel that already exists. The best way, of course, is to start the script by actually checking if the tunnel is already there:
# Exit if network device "tun0" exists.
ip link show dev tun0 >/dev/null 2>&1 && exit 0
Additionally, the scripts in if-up.d etc. run for every interface that is brought up. As Jeff correctly observes, the if-*.d scripts receive no arguments specifying e.g. which interface is coming up.
Instead, per the interfaces(5) man page:
There exists for each of the above mentioned options a directory
/etc/network/if-<option>.d/ [...]
All of these commands have access to the following environment vari‐
ables.
IFACE physical name of the interface being processed
LOGICAL
logical name of the interface being processed
[... and more ...]
The solution is to start the script with a check for the correct IFACE value, e.g.:
# Exit if we're not starting "eth0".
[ "$IFACE" = 'eth0' ] || exit 0
Otherwise, the script will run for every network device, including lo, at which point it may be too early to establish a tunnel.
That said, my issue was it was executing the script for the lo interface in addition to my eth0 connection. I took one of the steps which was to program your script with the logic to not run more than once, but to only run it once without adjusting the code just specify the interface to be used
before execution.
If I wanted to go back and solve this on the sh level, I'd simply need to update my script with this line since the interface I want to use is my Ethernet connection
[ "$IFACE" = 'eth0' ] || exit 0
sleep 269
sh -c "python /dir/to/bot.py >> /dir/to/log" & disown
add a comment |
Looking more into 16.04 if-up.d/, I found a similar question for someone running Debian 7.3 and found the answer. It is not a bug, and the issue I experienced is explained here in @Søren Løvborg's answer:
In general, ifup / ifdown does not guarantee that your script only runs once. Thus your script has to be idempotent; that is, contain its own logic not to establish a tunnel that already exists. The best way, of course, is to start the script by actually checking if the tunnel is already there:
# Exit if network device "tun0" exists.
ip link show dev tun0 >/dev/null 2>&1 && exit 0
Additionally, the scripts in if-up.d etc. run for every interface that is brought up. As Jeff correctly observes, the if-*.d scripts receive no arguments specifying e.g. which interface is coming up.
Instead, per the interfaces(5) man page:
There exists for each of the above mentioned options a directory
/etc/network/if-<option>.d/ [...]
All of these commands have access to the following environment vari‐
ables.
IFACE physical name of the interface being processed
LOGICAL
logical name of the interface being processed
[... and more ...]
The solution is to start the script with a check for the correct IFACE value, e.g.:
# Exit if we're not starting "eth0".
[ "$IFACE" = 'eth0' ] || exit 0
Otherwise, the script will run for every network device, including lo, at which point it may be too early to establish a tunnel.
That said, my issue was it was executing the script for the lo interface in addition to my eth0 connection. I took one of the steps which was to program your script with the logic to not run more than once, but to only run it once without adjusting the code just specify the interface to be used
before execution.
If I wanted to go back and solve this on the sh level, I'd simply need to update my script with this line since the interface I want to use is my Ethernet connection
[ "$IFACE" = 'eth0' ] || exit 0
sleep 269
sh -c "python /dir/to/bot.py >> /dir/to/log" & disown
add a comment |
Looking more into 16.04 if-up.d/, I found a similar question for someone running Debian 7.3 and found the answer. It is not a bug, and the issue I experienced is explained here in @Søren Løvborg's answer:
In general, ifup / ifdown does not guarantee that your script only runs once. Thus your script has to be idempotent; that is, contain its own logic not to establish a tunnel that already exists. The best way, of course, is to start the script by actually checking if the tunnel is already there:
# Exit if network device "tun0" exists.
ip link show dev tun0 >/dev/null 2>&1 && exit 0
Additionally, the scripts in if-up.d etc. run for every interface that is brought up. As Jeff correctly observes, the if-*.d scripts receive no arguments specifying e.g. which interface is coming up.
Instead, per the interfaces(5) man page:
There exists for each of the above mentioned options a directory
/etc/network/if-<option>.d/ [...]
All of these commands have access to the following environment vari‐
ables.
IFACE physical name of the interface being processed
LOGICAL
logical name of the interface being processed
[... and more ...]
The solution is to start the script with a check for the correct IFACE value, e.g.:
# Exit if we're not starting "eth0".
[ "$IFACE" = 'eth0' ] || exit 0
Otherwise, the script will run for every network device, including lo, at which point it may be too early to establish a tunnel.
That said, my issue was it was executing the script for the lo interface in addition to my eth0 connection. I took one of the steps which was to program your script with the logic to not run more than once, but to only run it once without adjusting the code just specify the interface to be used
before execution.
If I wanted to go back and solve this on the sh level, I'd simply need to update my script with this line since the interface I want to use is my Ethernet connection
[ "$IFACE" = 'eth0' ] || exit 0
sleep 269
sh -c "python /dir/to/bot.py >> /dir/to/log" & disown
Looking more into 16.04 if-up.d/, I found a similar question for someone running Debian 7.3 and found the answer. It is not a bug, and the issue I experienced is explained here in @Søren Løvborg's answer:
In general, ifup / ifdown does not guarantee that your script only runs once. Thus your script has to be idempotent; that is, contain its own logic not to establish a tunnel that already exists. The best way, of course, is to start the script by actually checking if the tunnel is already there:
# Exit if network device "tun0" exists.
ip link show dev tun0 >/dev/null 2>&1 && exit 0
Additionally, the scripts in if-up.d etc. run for every interface that is brought up. As Jeff correctly observes, the if-*.d scripts receive no arguments specifying e.g. which interface is coming up.
Instead, per the interfaces(5) man page:
There exists for each of the above mentioned options a directory
/etc/network/if-<option>.d/ [...]
All of these commands have access to the following environment vari‐
ables.
IFACE physical name of the interface being processed
LOGICAL
logical name of the interface being processed
[... and more ...]
The solution is to start the script with a check for the correct IFACE value, e.g.:
# Exit if we're not starting "eth0".
[ "$IFACE" = 'eth0' ] || exit 0
Otherwise, the script will run for every network device, including lo, at which point it may be too early to establish a tunnel.
That said, my issue was it was executing the script for the lo interface in addition to my eth0 connection. I took one of the steps which was to program your script with the logic to not run more than once, but to only run it once without adjusting the code just specify the interface to be used
before execution.
If I wanted to go back and solve this on the sh level, I'd simply need to update my script with this line since the interface I want to use is my Ethernet connection
[ "$IFACE" = 'eth0' ] || exit 0
sleep 269
sh -c "python /dir/to/bot.py >> /dir/to/log" & disown
edited Dec 6 at 1:52
answered Dec 5 at 23:32
saniboy
164
164
add a comment |
add a comment |
Thanks for contributing an answer to Ask Ubuntu!
- 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.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- 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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2faskubuntu.com%2fquestions%2f1098775%2fif-up-d-launches-two-instances-of-a-single-script%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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