1

Is there a way to change the initial shell used by the atd job scheduling service? Esp. in Ubuntu.

at by default uses /bin/sh in every Linux and Solaris I've deployed products on.

GNU's crontab does give you the option to set SHELL=/bin/bash as the default for entries that are inline/don't call a script having own shebang line.

I am aware one can do

at teatime <<< 'bash -c "stuff-better-run-on-bash" '

but such workarounds pose other problems.

voretaq7
  • 79,345
  • 17
  • 128
  • 213
Marcos
  • 113
  • 12

3 Answers3

2

For CentOS and related the environment variable SHELL is read when the at command is issued and this is used as the shell to execute the commands or if it is unset then the user's login shell is used. It looks like Ubuntu ignores this although it does warn you - warning: commands will be executed using /bin/sh. Can you not just write your commands in a file and put a shebang at the top ?

#!/bin/bash
milk
sugar

then run it as

at teatime -f script
user9517
  • 114,104
  • 20
  • 206
  • 289
  • Not really. My programs frequently offshoot minor and random tasks to `at` in the very convenient hit-and-run inline style. Other times they rely (very much) on simply `at now` in favor of `cmd1 paramsXYZ &>> cmd1pipe || cmd2 params2 & disown` because of the need to completely dissociate parent-child pid, gid and sid relationships. – Marcos Mar 05 '12 at 18:45
  • In that case at least in respect of Ubuntu you're out of luck. – user9517 Mar 05 '12 at 19:19
0

Not exactly what you want, perhaps, but you could always have your at job run a shell script, with the shell of your choice, no?

DictatorBob
  • 1,614
  • 11
  • 15
0

I don't like it but one workaround is to immediately modify line 1 of the newly spooled job.

master@chopin~/dev Sat Mar 10,20:52:58$ (4800) atq
616 Tue Mar 13 19:17:00 2012 a master
589 Mon Mar 12 16:16:00 2012 a master
617 Tue Mar 13 19:35:00 2012 a master
591 Mon Mar 12 16:23:00 2012 a master
447 Wed Mar 14 09:25:00 2012 a master
586 Mon Mar 12 15:45:00 2012 a master

master@chopin~/dev Sat Mar 10,20:53:01$ (4800) at -c 447
#!/bin/sh
# atrun uid=1000 gid=1000
# mail master 0
umask 22
...

So that strategy would be to write a wrapper on top of at that

  1. intercepts its $jobid when at is run underneath Not needed
  2. changes the shebang shell line of the newest file in /var/spool/cron/atjobs/ :

sudo <<< 'cd /var/spool/cron/atjobs/ && sed -i -e "1s/\#!\/bin\/sh/\#!\/bin\/bash/" $(ls -1t |head -n1)'

Might be a race condition in case of the at now by-itself timespec, unless perhaps additional time (like 1 sec) is artificially added. Though in my own use cases, I really need it run now not in 1 sec.

Anyway that's too much of a system hack to comfortably make my scripts use.

user9517
  • 114,104
  • 20
  • 206
  • 289
Marcos
  • 113
  • 12
  • testing1..2..3... did the post somehow swallow my backslashes in the sed expression? it should be `"1s/\#!\/bin\/sh/\#!\/bin\/bash/"` – Marcos Mar 10 '12 at 21:23