25

I have some commands in my .profile that I want to invoke from my crontab.

For example, if I have,

alias notify-me="~/bin/notify.pl -u user1"
alias notify-team="~/bin/notify.pl -u user1 user2 user3 user4 ...."

I'd like to just invoke the alias

0 11 * * * notify-team

so if the list in my .profile is updated, I don't have to update the crontab, too. However, I don't seem to be able to use aliases in my crontab. Is there a work around?

I tried the suggestions here to set up the environment (e.g. /bin/bash -lc and the script-wrapper script). It seems like that works for scripts but not aliases.

Any ideas?

1
  • Thanks, all for the useful info. Couple possible solutions here including my own. I ultimately modified artifex's original idea to something more useful for my situation. Chris provided the necessary info to do it with separate scripts. Mar 12, 2010 at 23:22

7 Answers 7

12

From the manpage regarding aliases:

Note aliases are not expanded by default in  non-interactive  shell,
and  it  can  be  enabled  by  setting  the 'expand_aliases'
shell option using shopt.

So try using shopt -s expand_aliases at the start of your sourcing script. This should let you use Warner's suggestion.

5
  • This is on for me on CentOS5 by default. Cool note though.
    – Warner
    Mar 4, 2010 at 21:17
  • Probably not in a script, though. Try creating a test script that outputs shopt expand_aliases. I'm betting it's off. It is in my RHEL 5.3 box. Mar 4, 2010 at 22:09
  • You hit the nail on the head. +1
    – Warner
    Mar 4, 2010 at 22:32
  • +1 Thx for pointing this out. It gets me most of the way to a solution, but I still end up having to create another file. I was hoping to do it without that. Mar 6, 2010 at 3:33
  • Keith, I had the same issue but doing eval 'foo' in crontab did the trick. Jun 19, 2010 at 0:56
10

bash -c with "source" should work:

0 11 * * * bash -c "source .profile && notify-team"

this might also work. the period means "source"

0 11 * * * . .profile && notify-team
6

As Chris identified, the default shell option for non-interactive shells is to not expand aliases. Here's a solution I've found to work.

Write a script, enable the shell option, and source your aliases. Be particularly aware that .bashrc is sourced at execution, which is why it has to be sourced again after enabling expand_aliases.

My apologies for the initially incorrect recommendation. This was more obscure than I initially expected it to be.

Script:

#!/bin/bash
shopt -s expand_aliases
source /home/wmoore/.bashrc
notify-team
8
  • Thx, but I've tried that already. Can you confirm that it works on your system? I've also tried /bin/bash -lc source ~/.profile; notify-team and other variations. Also I prefer not to have a separate script for each alias. That defeats the purpose of avoiding duplication. Mar 4, 2010 at 19:03
  • I should have included the error from crontab: "command not found" on every variation that I've tried. Mar 4, 2010 at 19:05
  • Edited with a tested recommendation.
    – Warner
    Mar 4, 2010 at 22:35
  • Thx for the updated example. I think if you add -l to your 1st line you can get rid of your 3rd. Mar 6, 2010 at 4:25
  • Ah, good call-- login shell would have expand_aliases enabled.
    – Warner
    Mar 6, 2010 at 4:32
1

I like artifex's idea of grabbing the alias from the file and then reusing it, since I couldn't find a way to expand/reuse aliases directly. (Other solutions still required another script.)

So I wrote this function and put it in my .profile:

grab-alias () { sed -n '/alias\s*'$1'\s*=/ {s/[^'\'']*.//;s/'\''\s*$//p}' /home/bentrupk/.profile; }

Then I was able to use it in my crontab for various aliases like this:

0 11 * * * /bin/bash -lc 'x=`grab-alias notify-team`; $x'
0 7 * * * /bin/bash -lc 'x=`grab-alias notify-me`; $x'

etc.

Yay, code reuse! Thanks, all.

2
  • 3
    that is pure evil.
    – Justin
    Mar 6, 2010 at 6:01
  • If I could use the alias directly, I would. That's the point of the question. You're welcome to propose another solution, but I'll take this solution over lots of 2-3 line files cluttering up a directory - which is what will happen as I add additional notification schemes or decide to reuse some of my other aliases. Mar 6, 2010 at 6:32
1

Really the simplest thing you could do would be to create

~/bin/notify-me with

#!/bin/sh
~/bin/notify.pl -u user1

~/bin/notify-team with

#!/bin/sh
~/bin/notify.pl -u user1 user2 user3 user4 ....

shell aliases are complicated to maintain and to integrate into other systems, as you've seen. the best thing to do is to turn them into full fledged commands that won't have funny environment issues.

1
  • 1
    Thanks for suggestion, but I never thought aliases were hard to maintain, and I'd rather maintain 1 file of aliases then maintain lots of wrapper files. The problem was executing the aliases in a cron job. Mar 6, 2010 at 6:30
0

bash -ic "notify-team" is best option. It makes alias available in crontab. You may further add a & for background as we are using a 'interactive' shell with -i , but in reality not interacting with it.

-3
0 11 * * * bash -ic "notify-team" > /log/file

works for me

1
  • 1
    Some explanation would improve the answer
    – Dave M
    Nov 4, 2016 at 10:48

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .