Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

In tcsh, the built-in sched command causes a command to be executed by the current shell at a specified time.

I have the following $HOME/.sched file (this is a simplified version of it):

setenv today `date +%F`
sched +00:01 sched 00:00 source $HOME/.sched

I then source $HOME/.sched in my $HOME/.cshrc.

This sets the environment variable $today to, for example, "2012-06-25", and automatically updates it to the current date every night at midnight. The job automatically reschedules itself every time it runs.

Note that the date command is invoked only once each day, and only when it's needed.

Is there a way to do this in bash? Note that the at command won't work; it invokes a command externally and cannot affect the current shell's environment.

(I know that I can type $(date +%F) rather than $today, but since I use this interactively, the extra typing is a significant burden.)

tcsh also has a number of special aliases that are executed automatically in certain circumstances:

The beepcmd, cwdcmd, periodic, precmd, postcmd, and jobcmd Special aliases can be set, respectively, to execute commands when the shell wants to ring the bell, when the working directory changes, every tperiod minutes, before each prompt, before each command gets executed, after each command gets executed, and when a job is started or is brought into the foreground.

Does bash have anything like these?

share|improve this question
add comment

5 Answers

This might give you an idea for a solution:

$ trap 'today=$(date)' 10
$ echo $today
$ sleep 8
$ kill -10 $$
$ echo $today

Now you can use at to send yourself ($$) a signal at the turn of the day.

share|improve this answer
add comment

If you're willing trade two backquotes for a dollar:

alias today='date +%F'
echo `today`

If you want the date in a variable, then updating it in PROMPT_COMMAND is the only way I can think of. You can avoid forking a process at each prompt by using the built-in variable SECONDS.

update_today () {
  if ((SECONDS/86400 > __last_today_update)); then
    ((__last_today_update = SECONDS/86400))
    today=$(date +%F)
  fi
}
PROMPT_COMMAND="update_today; $PROMPT_COMMAND"

Another approach is to insert your text through a key binding.

rl_insert () {
  READLINE_LINE=${READLINE_LINE:0:$READLINE_POINT}$1${READLINE_LINE:$READLINE_POINT}
  ((READLINE_POINT+=${#1}))
}
bind -x '"\C-xt":rl_insert "$(date +%F)"'
share|improve this answer
    
the readline approach is interesting, thanks for sharing. –  0xAF Jun 27 '12 at 11:13
    
The expression ((SECONDS/86400)) will change at 24-hour intervals after the shell started, not at midnight; / is truncating integer division (and $SECONDS is the number of seconds since the shell started). –  Keith Thompson Mar 4 '13 at 21:46
add comment

It doesn't look like bash has an equivalent feature, at least not with all of the qualities you describe. If you're looking for a "best of both worlds", zsh has sched features.

I do realize that might be just as unhelpful as the other answers though.

share|improve this answer
add comment

It sounds to me like you're looking for at:

~$ at now + 1 minute
warning: commands will be executed using /bin/sh
at> echo "test" | wall
at> 
job 2 at Mon Jun 25 17:51:00 2012

Broadcast Message from user@host                                              
        (somewhere) at 17:51 ...                                               

test                                                                           

Though, I just reread your question, and you're looking for something that will re-self-schedule itself. That'd be pretty easy to do with at calling a shell script that does what it needs to do and then sets up a new at job. However, at does run in its own subshell; not as the shell you invoke it from.

share|improve this answer
    
As I said in the question, at won't work; it can't set an environment variable in the shell from which it's invoked. –  Keith Thompson Jun 26 '12 at 1:54
add comment

Have you tried $PROMPT_COMMAND ? It is commonly used to set the xterm title to show CWD for example. It is executed when the prompt is shown. It may be possible to set your variable with this. The first disadvantage would be that your command will be executed everytime you press enter in the shell. The second would be that if are not active on your terminal for long time and the day passes, it will not get automatically set. It will get set after next enter on terminal.

# export PROMPT_COMMAND="export today=\`date\`"
# echo $today
Tue Jun 26 01:07:19 EEST 2012
# echo $today
Tue Jun 26 01:07:21 EEST 2012
# echo $today
Tue Jun 26 01:07:22 EEST 2012
share|improve this answer
    
That's likely to be the best I can do. The first disadvantage is what I'm most concerned about. We'll see of anyone else comes up with a better solution. –  Keith Thompson Jun 25 '12 at 22:15
    
unfortunately bash does not have a pre-command (if we consider $PROMPT_COMMAND as a post-command). –  0xAF Jun 25 '12 at 22:18
    
Pre- vs. post- doesn't matter much; I can live with $today not being set correctly for the first command I execute after midnight. –  Keith Thompson Jun 26 '12 at 1:56
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.