Can you execute a Bash function with the `at` command?
I want to execute a Bash function at a scheduled time. I think the right tool for this is the at
command.
However, it doesn't seem to be working.
function stupid () {
date
}
export -f stupid
cat << EOM | at now + 1 minute
stupid
EOM
After waiting the minute, I check my mail and this is the error I see:
sh: line 41: syntax error near unexpected token `=() { date"
"}'
sh: line 41: `"}; export BASH_FUNC_stupid()'
I don't understand what's going wrong here, especially since I know the function works.
$ stupid
Fri May 29 21:05:38 UTC 2015
Looking at the error, I think the incorrect shell is being used to execute the function (sh
as opposed to bash
), but if I check $SHELL
I see it points to /bin/bash
, and the man page for at
says:
$ echo $SHELL
/bin/bash
$ man at
...
SHELL The value of the SHELL environment variable at the time
of at invocation will determine which shell is used to
execute the at job commands.
So Bash should be the shell running my function.
What going on here? Is there a way to get my Bash function to run with at
?
bash environment-variables function at
add a comment |
I want to execute a Bash function at a scheduled time. I think the right tool for this is the at
command.
However, it doesn't seem to be working.
function stupid () {
date
}
export -f stupid
cat << EOM | at now + 1 minute
stupid
EOM
After waiting the minute, I check my mail and this is the error I see:
sh: line 41: syntax error near unexpected token `=() { date"
"}'
sh: line 41: `"}; export BASH_FUNC_stupid()'
I don't understand what's going wrong here, especially since I know the function works.
$ stupid
Fri May 29 21:05:38 UTC 2015
Looking at the error, I think the incorrect shell is being used to execute the function (sh
as opposed to bash
), but if I check $SHELL
I see it points to /bin/bash
, and the man page for at
says:
$ echo $SHELL
/bin/bash
$ man at
...
SHELL The value of the SHELL environment variable at the time
of at invocation will determine which shell is used to
execute the at job commands.
So Bash should be the shell running my function.
What going on here? Is there a way to get my Bash function to run with at
?
bash environment-variables function at
1
lists.gnu.org/archive/html/bug-bash/2014-09/msg00251.html
– llua
May 29 '15 at 21:56
@llua - Great find. I think I am running into the same issue, which is apparently a problem with Bash. Here's a similar report on the Red Hat bug tracker (linked to from that thread). For the record, I am runningGNU bash, version 4.1.2(1)-release
, which predates the shellshock fixes discussed in that thread by a few years. So perhaps it's not exactly the same issue. I should try with the latest release of Bash to see if this has been fixed.
– Nick Chammas
May 29 '15 at 22:22
Wow, this is weird. If I upgrade to the latest (I think) release,4.3.30(1)-release
and try the original snippet from my question, I now get:/bin/bash: line 1: stupid: command not found
. So now it looks likebash
and notsh
is running, which is good, but the function is no longer accessible.
– Nick Chammas
May 29 '15 at 22:49
Even weirder on Bash 4.3.30: If I submitbash -c 'stupid'
toat
instead of juststupid
, I get the original syntax error message withsh:
. I'm lost now.¯_(ツ)_/¯
– Nick Chammas
May 29 '15 at 22:51
add a comment |
I want to execute a Bash function at a scheduled time. I think the right tool for this is the at
command.
However, it doesn't seem to be working.
function stupid () {
date
}
export -f stupid
cat << EOM | at now + 1 minute
stupid
EOM
After waiting the minute, I check my mail and this is the error I see:
sh: line 41: syntax error near unexpected token `=() { date"
"}'
sh: line 41: `"}; export BASH_FUNC_stupid()'
I don't understand what's going wrong here, especially since I know the function works.
$ stupid
Fri May 29 21:05:38 UTC 2015
Looking at the error, I think the incorrect shell is being used to execute the function (sh
as opposed to bash
), but if I check $SHELL
I see it points to /bin/bash
, and the man page for at
says:
$ echo $SHELL
/bin/bash
$ man at
...
SHELL The value of the SHELL environment variable at the time
of at invocation will determine which shell is used to
execute the at job commands.
So Bash should be the shell running my function.
What going on here? Is there a way to get my Bash function to run with at
?
bash environment-variables function at
I want to execute a Bash function at a scheduled time. I think the right tool for this is the at
command.
However, it doesn't seem to be working.
function stupid () {
date
}
export -f stupid
cat << EOM | at now + 1 minute
stupid
EOM
After waiting the minute, I check my mail and this is the error I see:
sh: line 41: syntax error near unexpected token `=() { date"
"}'
sh: line 41: `"}; export BASH_FUNC_stupid()'
I don't understand what's going wrong here, especially since I know the function works.
$ stupid
Fri May 29 21:05:38 UTC 2015
Looking at the error, I think the incorrect shell is being used to execute the function (sh
as opposed to bash
), but if I check $SHELL
I see it points to /bin/bash
, and the man page for at
says:
$ echo $SHELL
/bin/bash
$ man at
...
SHELL The value of the SHELL environment variable at the time
of at invocation will determine which shell is used to
execute the at job commands.
So Bash should be the shell running my function.
What going on here? Is there a way to get my Bash function to run with at
?
bash environment-variables function at
bash environment-variables function at
edited May 29 '15 at 22:43
Gilles
536k12810821600
536k12810821600
asked May 29 '15 at 21:12
Nick ChammasNick Chammas
1286
1286
1
lists.gnu.org/archive/html/bug-bash/2014-09/msg00251.html
– llua
May 29 '15 at 21:56
@llua - Great find. I think I am running into the same issue, which is apparently a problem with Bash. Here's a similar report on the Red Hat bug tracker (linked to from that thread). For the record, I am runningGNU bash, version 4.1.2(1)-release
, which predates the shellshock fixes discussed in that thread by a few years. So perhaps it's not exactly the same issue. I should try with the latest release of Bash to see if this has been fixed.
– Nick Chammas
May 29 '15 at 22:22
Wow, this is weird. If I upgrade to the latest (I think) release,4.3.30(1)-release
and try the original snippet from my question, I now get:/bin/bash: line 1: stupid: command not found
. So now it looks likebash
and notsh
is running, which is good, but the function is no longer accessible.
– Nick Chammas
May 29 '15 at 22:49
Even weirder on Bash 4.3.30: If I submitbash -c 'stupid'
toat
instead of juststupid
, I get the original syntax error message withsh:
. I'm lost now.¯_(ツ)_/¯
– Nick Chammas
May 29 '15 at 22:51
add a comment |
1
lists.gnu.org/archive/html/bug-bash/2014-09/msg00251.html
– llua
May 29 '15 at 21:56
@llua - Great find. I think I am running into the same issue, which is apparently a problem with Bash. Here's a similar report on the Red Hat bug tracker (linked to from that thread). For the record, I am runningGNU bash, version 4.1.2(1)-release
, which predates the shellshock fixes discussed in that thread by a few years. So perhaps it's not exactly the same issue. I should try with the latest release of Bash to see if this has been fixed.
– Nick Chammas
May 29 '15 at 22:22
Wow, this is weird. If I upgrade to the latest (I think) release,4.3.30(1)-release
and try the original snippet from my question, I now get:/bin/bash: line 1: stupid: command not found
. So now it looks likebash
and notsh
is running, which is good, but the function is no longer accessible.
– Nick Chammas
May 29 '15 at 22:49
Even weirder on Bash 4.3.30: If I submitbash -c 'stupid'
toat
instead of juststupid
, I get the original syntax error message withsh:
. I'm lost now.¯_(ツ)_/¯
– Nick Chammas
May 29 '15 at 22:51
1
1
lists.gnu.org/archive/html/bug-bash/2014-09/msg00251.html
– llua
May 29 '15 at 21:56
lists.gnu.org/archive/html/bug-bash/2014-09/msg00251.html
– llua
May 29 '15 at 21:56
@llua - Great find. I think I am running into the same issue, which is apparently a problem with Bash. Here's a similar report on the Red Hat bug tracker (linked to from that thread). For the record, I am running
GNU bash, version 4.1.2(1)-release
, which predates the shellshock fixes discussed in that thread by a few years. So perhaps it's not exactly the same issue. I should try with the latest release of Bash to see if this has been fixed.– Nick Chammas
May 29 '15 at 22:22
@llua - Great find. I think I am running into the same issue, which is apparently a problem with Bash. Here's a similar report on the Red Hat bug tracker (linked to from that thread). For the record, I am running
GNU bash, version 4.1.2(1)-release
, which predates the shellshock fixes discussed in that thread by a few years. So perhaps it's not exactly the same issue. I should try with the latest release of Bash to see if this has been fixed.– Nick Chammas
May 29 '15 at 22:22
Wow, this is weird. If I upgrade to the latest (I think) release,
4.3.30(1)-release
and try the original snippet from my question, I now get: /bin/bash: line 1: stupid: command not found
. So now it looks like bash
and not sh
is running, which is good, but the function is no longer accessible.– Nick Chammas
May 29 '15 at 22:49
Wow, this is weird. If I upgrade to the latest (I think) release,
4.3.30(1)-release
and try the original snippet from my question, I now get: /bin/bash: line 1: stupid: command not found
. So now it looks like bash
and not sh
is running, which is good, but the function is no longer accessible.– Nick Chammas
May 29 '15 at 22:49
Even weirder on Bash 4.3.30: If I submit
bash -c 'stupid'
to at
instead of just stupid
, I get the original syntax error message with sh:
. I'm lost now. ¯_(ツ)_/¯
– Nick Chammas
May 29 '15 at 22:51
Even weirder on Bash 4.3.30: If I submit
bash -c 'stupid'
to at
instead of just stupid
, I get the original syntax error message with sh:
. I'm lost now. ¯_(ツ)_/¯
– Nick Chammas
May 29 '15 at 22:51
add a comment |
2 Answers
2
active
oldest
votes
Bash functions are exported via the environment. The at
command makes the environment, the umask and the current directory of the calling process available to the script by generating shell code that reproduces the environment. The script executed by your at job is something like this:
#!/bin/bash
umask 022
cd /home/nick
PATH=/usr/local/bin:/usr/bin:/bin; export PATH
HOME=/home/nick; export HOME
…
stupid
Under older versions of bash, functions were exported as a variable with the name of the function and a value starting with ()
and consisting of code to define the function, e.g.
stupid="() {
date
}"; export stupid
This made many scenarios vulnerable to a security hole, the Shellshock bug (found by Stéphane Chazelas), which allowed anyone able to inject the content of an environment variable under any name to execute arbitrary code in a bash script. Versions of bash where with a Shellshock fix use a different way: they store the function definition in a variable whose name contains characters that are not found in environment variables and that shells do not parse as assignments.
BASH_FUNC_stupid%%="() {
date
}"; export stupid
Due to the %
, this is not valid sh syntax, not even in bash, so the at job fails, whether it even attempts to use the function or not. The Debian version of at, which is used in many Linux distributions, was changed in version 3.16 to export only variables that have valid names in shell scripts. Thus newer versions of at don't pass post-Shellshock bash exported functions through, whereas older ones error out.
Even with pre-Shellshock versions of bash, the exported function only works in bash scripts launched from the at job, not in the at job itself. In the at job itself, even if it's executed by bash, stupid
is just another environment variable; bash only imports functions when it starts.
To export functions to an at job regardless of the bash or at version, put them in a file and source that file from your job, or include them directly in your job. To print out all defined functions in a format that can be read back, use declare -f
.
{ declare -f; cat << EOM; } | at now + 1 minute
stupid
EOM
Thank you for the thorough answer and history behind this behavior. One thing I think this answer doesn't explain, is whysh
shows up in the error messages when$SHELL
is correctly set to/bin/bash
and that is supposedly what determines which shell executes the job. That just may be another artifact of the older version of Bash I was using. But in any case, it sounds like the headache-free solution to do what I want is to put my functions in a file and source them from the job, as you recommend.
– Nick Chammas
May 30 '15 at 22:07
@NickChammas What version of at do you have, on what distribution? The one maintained by Debian and used by many Linux distributions (and I think shared common ancestry with *BSD) always runs the supplied code with sh. It tells mewarning: commands will be executed using /bin/sh
when I run it. Given the passage you quote from your man page, you're using a different or patched version, which come to think of it might mean that it works differently (though with the same symptoms here).
– Gilles
May 30 '15 at 22:20
at -V
gives3.1.10
. I'm running on Amazon Linux AMI release 2013.03.
– Nick Chammas
Jun 1 '15 at 20:08
add a comment |
Well, you already know you get mail. That's pretty cool, because you definitely can execute a bash
function when mail arrives.
This is from man bash
:
$MAILPATH
A colon-separated list of filenames to be checked for mail. The message to be printed when mail arrives in a particular file may be specified by separating the filename from the message with a ?. When used in the text of the message,
$_
expands to the name of the current mailfile. Example:
MAILPATH='/var/mail/bfox?"You have mail":~/shell-mail?"$_ has mail!"'
bash
supplies a default value for this variable, but the location of the user mail files that it uses is system dependent (e.g.,/var/mail/$USER
).
Incidentally, $_
is not the only expansion that might occur in that context - you can expand practically anything, to include command substitutions. In fact, you don't necessarily need to print anything at all. And the files don't necessarily need to contain mail either - the shell will attempt to notify when a check performed every $MAILCHECK
seconds indicates a file has been modified since it last had a look.
Still though, the way shells handle $MAILxxxx
is usually dependent on prompts - which is to say that regardless of $MAILCHECK
's value if you don't pull a new prompt at the right time you don't get notified - and won't until you trigger the next prompt. I'm not certain about this, but it maybe set -b
would affect that.
In any case, there is more than one way to do that kind of thing. Perhaps most obvious would be to use a signal - schedule an at
job like:
echo kill -USR1 "$$" | at now + 1 minute
trap some_func USR1
And see what happens.
add a comment |
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
});
}
});
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%2funix.stackexchange.com%2fquestions%2f206405%2fcan-you-execute-a-bash-function-with-the-at-command%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Bash functions are exported via the environment. The at
command makes the environment, the umask and the current directory of the calling process available to the script by generating shell code that reproduces the environment. The script executed by your at job is something like this:
#!/bin/bash
umask 022
cd /home/nick
PATH=/usr/local/bin:/usr/bin:/bin; export PATH
HOME=/home/nick; export HOME
…
stupid
Under older versions of bash, functions were exported as a variable with the name of the function and a value starting with ()
and consisting of code to define the function, e.g.
stupid="() {
date
}"; export stupid
This made many scenarios vulnerable to a security hole, the Shellshock bug (found by Stéphane Chazelas), which allowed anyone able to inject the content of an environment variable under any name to execute arbitrary code in a bash script. Versions of bash where with a Shellshock fix use a different way: they store the function definition in a variable whose name contains characters that are not found in environment variables and that shells do not parse as assignments.
BASH_FUNC_stupid%%="() {
date
}"; export stupid
Due to the %
, this is not valid sh syntax, not even in bash, so the at job fails, whether it even attempts to use the function or not. The Debian version of at, which is used in many Linux distributions, was changed in version 3.16 to export only variables that have valid names in shell scripts. Thus newer versions of at don't pass post-Shellshock bash exported functions through, whereas older ones error out.
Even with pre-Shellshock versions of bash, the exported function only works in bash scripts launched from the at job, not in the at job itself. In the at job itself, even if it's executed by bash, stupid
is just another environment variable; bash only imports functions when it starts.
To export functions to an at job regardless of the bash or at version, put them in a file and source that file from your job, or include them directly in your job. To print out all defined functions in a format that can be read back, use declare -f
.
{ declare -f; cat << EOM; } | at now + 1 minute
stupid
EOM
Thank you for the thorough answer and history behind this behavior. One thing I think this answer doesn't explain, is whysh
shows up in the error messages when$SHELL
is correctly set to/bin/bash
and that is supposedly what determines which shell executes the job. That just may be another artifact of the older version of Bash I was using. But in any case, it sounds like the headache-free solution to do what I want is to put my functions in a file and source them from the job, as you recommend.
– Nick Chammas
May 30 '15 at 22:07
@NickChammas What version of at do you have, on what distribution? The one maintained by Debian and used by many Linux distributions (and I think shared common ancestry with *BSD) always runs the supplied code with sh. It tells mewarning: commands will be executed using /bin/sh
when I run it. Given the passage you quote from your man page, you're using a different or patched version, which come to think of it might mean that it works differently (though with the same symptoms here).
– Gilles
May 30 '15 at 22:20
at -V
gives3.1.10
. I'm running on Amazon Linux AMI release 2013.03.
– Nick Chammas
Jun 1 '15 at 20:08
add a comment |
Bash functions are exported via the environment. The at
command makes the environment, the umask and the current directory of the calling process available to the script by generating shell code that reproduces the environment. The script executed by your at job is something like this:
#!/bin/bash
umask 022
cd /home/nick
PATH=/usr/local/bin:/usr/bin:/bin; export PATH
HOME=/home/nick; export HOME
…
stupid
Under older versions of bash, functions were exported as a variable with the name of the function and a value starting with ()
and consisting of code to define the function, e.g.
stupid="() {
date
}"; export stupid
This made many scenarios vulnerable to a security hole, the Shellshock bug (found by Stéphane Chazelas), which allowed anyone able to inject the content of an environment variable under any name to execute arbitrary code in a bash script. Versions of bash where with a Shellshock fix use a different way: they store the function definition in a variable whose name contains characters that are not found in environment variables and that shells do not parse as assignments.
BASH_FUNC_stupid%%="() {
date
}"; export stupid
Due to the %
, this is not valid sh syntax, not even in bash, so the at job fails, whether it even attempts to use the function or not. The Debian version of at, which is used in many Linux distributions, was changed in version 3.16 to export only variables that have valid names in shell scripts. Thus newer versions of at don't pass post-Shellshock bash exported functions through, whereas older ones error out.
Even with pre-Shellshock versions of bash, the exported function only works in bash scripts launched from the at job, not in the at job itself. In the at job itself, even if it's executed by bash, stupid
is just another environment variable; bash only imports functions when it starts.
To export functions to an at job regardless of the bash or at version, put them in a file and source that file from your job, or include them directly in your job. To print out all defined functions in a format that can be read back, use declare -f
.
{ declare -f; cat << EOM; } | at now + 1 minute
stupid
EOM
Thank you for the thorough answer and history behind this behavior. One thing I think this answer doesn't explain, is whysh
shows up in the error messages when$SHELL
is correctly set to/bin/bash
and that is supposedly what determines which shell executes the job. That just may be another artifact of the older version of Bash I was using. But in any case, it sounds like the headache-free solution to do what I want is to put my functions in a file and source them from the job, as you recommend.
– Nick Chammas
May 30 '15 at 22:07
@NickChammas What version of at do you have, on what distribution? The one maintained by Debian and used by many Linux distributions (and I think shared common ancestry with *BSD) always runs the supplied code with sh. It tells mewarning: commands will be executed using /bin/sh
when I run it. Given the passage you quote from your man page, you're using a different or patched version, which come to think of it might mean that it works differently (though with the same symptoms here).
– Gilles
May 30 '15 at 22:20
at -V
gives3.1.10
. I'm running on Amazon Linux AMI release 2013.03.
– Nick Chammas
Jun 1 '15 at 20:08
add a comment |
Bash functions are exported via the environment. The at
command makes the environment, the umask and the current directory of the calling process available to the script by generating shell code that reproduces the environment. The script executed by your at job is something like this:
#!/bin/bash
umask 022
cd /home/nick
PATH=/usr/local/bin:/usr/bin:/bin; export PATH
HOME=/home/nick; export HOME
…
stupid
Under older versions of bash, functions were exported as a variable with the name of the function and a value starting with ()
and consisting of code to define the function, e.g.
stupid="() {
date
}"; export stupid
This made many scenarios vulnerable to a security hole, the Shellshock bug (found by Stéphane Chazelas), which allowed anyone able to inject the content of an environment variable under any name to execute arbitrary code in a bash script. Versions of bash where with a Shellshock fix use a different way: they store the function definition in a variable whose name contains characters that are not found in environment variables and that shells do not parse as assignments.
BASH_FUNC_stupid%%="() {
date
}"; export stupid
Due to the %
, this is not valid sh syntax, not even in bash, so the at job fails, whether it even attempts to use the function or not. The Debian version of at, which is used in many Linux distributions, was changed in version 3.16 to export only variables that have valid names in shell scripts. Thus newer versions of at don't pass post-Shellshock bash exported functions through, whereas older ones error out.
Even with pre-Shellshock versions of bash, the exported function only works in bash scripts launched from the at job, not in the at job itself. In the at job itself, even if it's executed by bash, stupid
is just another environment variable; bash only imports functions when it starts.
To export functions to an at job regardless of the bash or at version, put them in a file and source that file from your job, or include them directly in your job. To print out all defined functions in a format that can be read back, use declare -f
.
{ declare -f; cat << EOM; } | at now + 1 minute
stupid
EOM
Bash functions are exported via the environment. The at
command makes the environment, the umask and the current directory of the calling process available to the script by generating shell code that reproduces the environment. The script executed by your at job is something like this:
#!/bin/bash
umask 022
cd /home/nick
PATH=/usr/local/bin:/usr/bin:/bin; export PATH
HOME=/home/nick; export HOME
…
stupid
Under older versions of bash, functions were exported as a variable with the name of the function and a value starting with ()
and consisting of code to define the function, e.g.
stupid="() {
date
}"; export stupid
This made many scenarios vulnerable to a security hole, the Shellshock bug (found by Stéphane Chazelas), which allowed anyone able to inject the content of an environment variable under any name to execute arbitrary code in a bash script. Versions of bash where with a Shellshock fix use a different way: they store the function definition in a variable whose name contains characters that are not found in environment variables and that shells do not parse as assignments.
BASH_FUNC_stupid%%="() {
date
}"; export stupid
Due to the %
, this is not valid sh syntax, not even in bash, so the at job fails, whether it even attempts to use the function or not. The Debian version of at, which is used in many Linux distributions, was changed in version 3.16 to export only variables that have valid names in shell scripts. Thus newer versions of at don't pass post-Shellshock bash exported functions through, whereas older ones error out.
Even with pre-Shellshock versions of bash, the exported function only works in bash scripts launched from the at job, not in the at job itself. In the at job itself, even if it's executed by bash, stupid
is just another environment variable; bash only imports functions when it starts.
To export functions to an at job regardless of the bash or at version, put them in a file and source that file from your job, or include them directly in your job. To print out all defined functions in a format that can be read back, use declare -f
.
{ declare -f; cat << EOM; } | at now + 1 minute
stupid
EOM
edited Jan 31 at 16:04
Stephen Kitt
171k24386462
171k24386462
answered May 29 '15 at 23:35
GillesGilles
536k12810821600
536k12810821600
Thank you for the thorough answer and history behind this behavior. One thing I think this answer doesn't explain, is whysh
shows up in the error messages when$SHELL
is correctly set to/bin/bash
and that is supposedly what determines which shell executes the job. That just may be another artifact of the older version of Bash I was using. But in any case, it sounds like the headache-free solution to do what I want is to put my functions in a file and source them from the job, as you recommend.
– Nick Chammas
May 30 '15 at 22:07
@NickChammas What version of at do you have, on what distribution? The one maintained by Debian and used by many Linux distributions (and I think shared common ancestry with *BSD) always runs the supplied code with sh. It tells mewarning: commands will be executed using /bin/sh
when I run it. Given the passage you quote from your man page, you're using a different or patched version, which come to think of it might mean that it works differently (though with the same symptoms here).
– Gilles
May 30 '15 at 22:20
at -V
gives3.1.10
. I'm running on Amazon Linux AMI release 2013.03.
– Nick Chammas
Jun 1 '15 at 20:08
add a comment |
Thank you for the thorough answer and history behind this behavior. One thing I think this answer doesn't explain, is whysh
shows up in the error messages when$SHELL
is correctly set to/bin/bash
and that is supposedly what determines which shell executes the job. That just may be another artifact of the older version of Bash I was using. But in any case, it sounds like the headache-free solution to do what I want is to put my functions in a file and source them from the job, as you recommend.
– Nick Chammas
May 30 '15 at 22:07
@NickChammas What version of at do you have, on what distribution? The one maintained by Debian and used by many Linux distributions (and I think shared common ancestry with *BSD) always runs the supplied code with sh. It tells mewarning: commands will be executed using /bin/sh
when I run it. Given the passage you quote from your man page, you're using a different or patched version, which come to think of it might mean that it works differently (though with the same symptoms here).
– Gilles
May 30 '15 at 22:20
at -V
gives3.1.10
. I'm running on Amazon Linux AMI release 2013.03.
– Nick Chammas
Jun 1 '15 at 20:08
Thank you for the thorough answer and history behind this behavior. One thing I think this answer doesn't explain, is why
sh
shows up in the error messages when $SHELL
is correctly set to /bin/bash
and that is supposedly what determines which shell executes the job. That just may be another artifact of the older version of Bash I was using. But in any case, it sounds like the headache-free solution to do what I want is to put my functions in a file and source them from the job, as you recommend.– Nick Chammas
May 30 '15 at 22:07
Thank you for the thorough answer and history behind this behavior. One thing I think this answer doesn't explain, is why
sh
shows up in the error messages when $SHELL
is correctly set to /bin/bash
and that is supposedly what determines which shell executes the job. That just may be another artifact of the older version of Bash I was using. But in any case, it sounds like the headache-free solution to do what I want is to put my functions in a file and source them from the job, as you recommend.– Nick Chammas
May 30 '15 at 22:07
@NickChammas What version of at do you have, on what distribution? The one maintained by Debian and used by many Linux distributions (and I think shared common ancestry with *BSD) always runs the supplied code with sh. It tells me
warning: commands will be executed using /bin/sh
when I run it. Given the passage you quote from your man page, you're using a different or patched version, which come to think of it might mean that it works differently (though with the same symptoms here).– Gilles
May 30 '15 at 22:20
@NickChammas What version of at do you have, on what distribution? The one maintained by Debian and used by many Linux distributions (and I think shared common ancestry with *BSD) always runs the supplied code with sh. It tells me
warning: commands will be executed using /bin/sh
when I run it. Given the passage you quote from your man page, you're using a different or patched version, which come to think of it might mean that it works differently (though with the same symptoms here).– Gilles
May 30 '15 at 22:20
at -V
gives 3.1.10
. I'm running on Amazon Linux AMI release 2013.03.– Nick Chammas
Jun 1 '15 at 20:08
at -V
gives 3.1.10
. I'm running on Amazon Linux AMI release 2013.03.– Nick Chammas
Jun 1 '15 at 20:08
add a comment |
Well, you already know you get mail. That's pretty cool, because you definitely can execute a bash
function when mail arrives.
This is from man bash
:
$MAILPATH
A colon-separated list of filenames to be checked for mail. The message to be printed when mail arrives in a particular file may be specified by separating the filename from the message with a ?. When used in the text of the message,
$_
expands to the name of the current mailfile. Example:
MAILPATH='/var/mail/bfox?"You have mail":~/shell-mail?"$_ has mail!"'
bash
supplies a default value for this variable, but the location of the user mail files that it uses is system dependent (e.g.,/var/mail/$USER
).
Incidentally, $_
is not the only expansion that might occur in that context - you can expand practically anything, to include command substitutions. In fact, you don't necessarily need to print anything at all. And the files don't necessarily need to contain mail either - the shell will attempt to notify when a check performed every $MAILCHECK
seconds indicates a file has been modified since it last had a look.
Still though, the way shells handle $MAILxxxx
is usually dependent on prompts - which is to say that regardless of $MAILCHECK
's value if you don't pull a new prompt at the right time you don't get notified - and won't until you trigger the next prompt. I'm not certain about this, but it maybe set -b
would affect that.
In any case, there is more than one way to do that kind of thing. Perhaps most obvious would be to use a signal - schedule an at
job like:
echo kill -USR1 "$$" | at now + 1 minute
trap some_func USR1
And see what happens.
add a comment |
Well, you already know you get mail. That's pretty cool, because you definitely can execute a bash
function when mail arrives.
This is from man bash
:
$MAILPATH
A colon-separated list of filenames to be checked for mail. The message to be printed when mail arrives in a particular file may be specified by separating the filename from the message with a ?. When used in the text of the message,
$_
expands to the name of the current mailfile. Example:
MAILPATH='/var/mail/bfox?"You have mail":~/shell-mail?"$_ has mail!"'
bash
supplies a default value for this variable, but the location of the user mail files that it uses is system dependent (e.g.,/var/mail/$USER
).
Incidentally, $_
is not the only expansion that might occur in that context - you can expand practically anything, to include command substitutions. In fact, you don't necessarily need to print anything at all. And the files don't necessarily need to contain mail either - the shell will attempt to notify when a check performed every $MAILCHECK
seconds indicates a file has been modified since it last had a look.
Still though, the way shells handle $MAILxxxx
is usually dependent on prompts - which is to say that regardless of $MAILCHECK
's value if you don't pull a new prompt at the right time you don't get notified - and won't until you trigger the next prompt. I'm not certain about this, but it maybe set -b
would affect that.
In any case, there is more than one way to do that kind of thing. Perhaps most obvious would be to use a signal - schedule an at
job like:
echo kill -USR1 "$$" | at now + 1 minute
trap some_func USR1
And see what happens.
add a comment |
Well, you already know you get mail. That's pretty cool, because you definitely can execute a bash
function when mail arrives.
This is from man bash
:
$MAILPATH
A colon-separated list of filenames to be checked for mail. The message to be printed when mail arrives in a particular file may be specified by separating the filename from the message with a ?. When used in the text of the message,
$_
expands to the name of the current mailfile. Example:
MAILPATH='/var/mail/bfox?"You have mail":~/shell-mail?"$_ has mail!"'
bash
supplies a default value for this variable, but the location of the user mail files that it uses is system dependent (e.g.,/var/mail/$USER
).
Incidentally, $_
is not the only expansion that might occur in that context - you can expand practically anything, to include command substitutions. In fact, you don't necessarily need to print anything at all. And the files don't necessarily need to contain mail either - the shell will attempt to notify when a check performed every $MAILCHECK
seconds indicates a file has been modified since it last had a look.
Still though, the way shells handle $MAILxxxx
is usually dependent on prompts - which is to say that regardless of $MAILCHECK
's value if you don't pull a new prompt at the right time you don't get notified - and won't until you trigger the next prompt. I'm not certain about this, but it maybe set -b
would affect that.
In any case, there is more than one way to do that kind of thing. Perhaps most obvious would be to use a signal - schedule an at
job like:
echo kill -USR1 "$$" | at now + 1 minute
trap some_func USR1
And see what happens.
Well, you already know you get mail. That's pretty cool, because you definitely can execute a bash
function when mail arrives.
This is from man bash
:
$MAILPATH
A colon-separated list of filenames to be checked for mail. The message to be printed when mail arrives in a particular file may be specified by separating the filename from the message with a ?. When used in the text of the message,
$_
expands to the name of the current mailfile. Example:
MAILPATH='/var/mail/bfox?"You have mail":~/shell-mail?"$_ has mail!"'
bash
supplies a default value for this variable, but the location of the user mail files that it uses is system dependent (e.g.,/var/mail/$USER
).
Incidentally, $_
is not the only expansion that might occur in that context - you can expand practically anything, to include command substitutions. In fact, you don't necessarily need to print anything at all. And the files don't necessarily need to contain mail either - the shell will attempt to notify when a check performed every $MAILCHECK
seconds indicates a file has been modified since it last had a look.
Still though, the way shells handle $MAILxxxx
is usually dependent on prompts - which is to say that regardless of $MAILCHECK
's value if you don't pull a new prompt at the right time you don't get notified - and won't until you trigger the next prompt. I'm not certain about this, but it maybe set -b
would affect that.
In any case, there is more than one way to do that kind of thing. Perhaps most obvious would be to use a signal - schedule an at
job like:
echo kill -USR1 "$$" | at now + 1 minute
trap some_func USR1
And see what happens.
answered May 30 '15 at 5:50
mikeservmikeserv
45.6k668157
45.6k668157
add a comment |
add a comment |
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.
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%2funix.stackexchange.com%2fquestions%2f206405%2fcan-you-execute-a-bash-function-with-the-at-command%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
1
lists.gnu.org/archive/html/bug-bash/2014-09/msg00251.html
– llua
May 29 '15 at 21:56
@llua - Great find. I think I am running into the same issue, which is apparently a problem with Bash. Here's a similar report on the Red Hat bug tracker (linked to from that thread). For the record, I am running
GNU bash, version 4.1.2(1)-release
, which predates the shellshock fixes discussed in that thread by a few years. So perhaps it's not exactly the same issue. I should try with the latest release of Bash to see if this has been fixed.– Nick Chammas
May 29 '15 at 22:22
Wow, this is weird. If I upgrade to the latest (I think) release,
4.3.30(1)-release
and try the original snippet from my question, I now get:/bin/bash: line 1: stupid: command not found
. So now it looks likebash
and notsh
is running, which is good, but the function is no longer accessible.– Nick Chammas
May 29 '15 at 22:49
Even weirder on Bash 4.3.30: If I submit
bash -c 'stupid'
toat
instead of juststupid
, I get the original syntax error message withsh:
. I'm lost now.¯_(ツ)_/¯
– Nick Chammas
May 29 '15 at 22:51