at job seems to be running using /bin/sh though I have a #!/bin/bash
I am trying to run a job using
at, and I have a
bash script (I do have
#!/bin/bash as the first line), but the job fails because of use of
]] in the script, I see the following in the
=sh: 58: [[: not found =sh: 58: [[: not found =sh: 58: [[: not found =sh: 58: [[: not found =sh: 58: [[: not found
/bin/sh is a link to
dash, but if I have the she-bang line as
#!/bin/bash in my script – should it not use
P.S If I just run the script on my
bash prompt – it works fine with no errors (and it has executable permissions).
I am adding the job like this:
$ at 1:30 am today -f /path/to/my/script.sh $ which bash /bin/bash $ ls -l /bin/sh lrwxrwxrwx 1 root root 4 Mar 30 2012 /bin/sh -> dash $ uname -a Linux server1 3.5.0-46-generic #70~precise1-Ubuntu SMP Thu Jan 9 23:55:12 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
read commands from standard input or a specified file which are to be executed at a later time, using /bin/sh.
a text file consisting of commands acceptable to the shell command language described in Shell Command Language.
That is, it’s required to be a POSIX
sh script. Bash allows Bashisms through even when it’s run as
dash is strict. The script isn’t run as an executable, but directly with
sh, so an arbitrary binary or a Python script won’t work either, for example.
What you may be able to do, though, is to force yourself into
bash anyway. Something like:
[ "$BASH_VERSION" ] || exec bash "/path/to/script"
at the top of the file should have the script re-execute itself with
bash when it isn’t already being interpreted that way. The shell won’t generate syntax errors for code it that execution doesn’t get to, so the later uses of
[[ won’t matter. You may be able to use
$0 instead of the path, but it seems to be inconsistent across
at implementations and none of the specifications imply it should work, so the path will be more reliable.
Determine a name of a command interpreter to be used to invoke the
at-job. If the variable is unset or null, sh shall be used. If it is
set to a value other than a name for sh, the implementation shall do
one of the following: use that shell; use sh; use the login shell from
the user database; or any of the preceding accompanied by a warning
diagnostic about which was chosen.
Some implementation of at can give you ability to chose which shell you want to run, like
-k for Korn shell,
-c for C-shell. And not all implementation of
SHELL to substitute
sh. So POSIX also guaranteed the reliable way to use another shell is explicit call it:
Some implementations do not allow substitution of different shells
using SHELL. System V systems, for example, have used the login shell
value for the user in /etc/passwd. To select reliably another command
interpreter, the user must include it as part of the script, such as:
$ at 1800
job … at … $
A simple way, using
bash to run your script is passing
bash script as stdin to
echo "bash /path/to/yourscript" | at <time>
echo "bash /path/to/yourscript" | at 16:30
bash /path/to/yourscript at 16:30 today.
My answer is similar to Gnouc’s, but I believe I have a better explanation of the “Why?”
When you say
at … -f /path/to/my/script.sh,
you are telling
at to read
It copies your script somewhere (probably somewhere under
at jobs daemon, can pass the script’s contents to
At this point, the
#!/bin/bash she-bang line is just a comment,
[[…]] usage is an error.
What you want to do is not give
at the contents of your script,
but give it the name, by
$ echo /path/to/my/script.sh | at 1:30 am today
$ at 1:30 am today /path/to/my/script.sh Ctrl+D
That way, the
/bin/sh will see
and will execute it as a command.
And then the she-bang line will do its job, causing
bash to be invoked.
P.S. My answer (like Gnouc’s) has the “feature” that,
if you change your script between now and 1:30 am today,
atd will run the modified version.
(This is in contrast to your approach, using
at makes a copy of your script when you run
In particular, if you delete or rename the script, nothing will run.