2

remind(1) provides a function shell() documented as follows:

   shell(s_cmd [,i_maxlen])
          Executes cmd as a system command, and returns the first 511
          characters  of  output resulting  from  cmd. Any  whitespace
          character in the output is converted to a space. Note that if
          RUN OFF has been executed, or the -r command-line option has
          been used, shell() will result in an error, and cmd will not be
          executed.

          …

I would like whatever s_cmd writes to stdout to be interpreted by remind itself. E. g.:

$ echo REM Sep 13 2018 MSG test >/tmp/test.rem
$ tail -2 ~/.reminders
SET tmp shell("cat /tmp/test.rem", -1)
$tmp

Where $tmp is my unsuccessful attempt at inserting the output of the command in the line above. When executing rem(1), it does not return an error but it does not interpolate $tmp either:

$ rem
Reminders for Thursday, 13th September, 2018 (today):

…
$tmp 

I assume that $tmp is interpreted as an implicit REM … statement.

(The INCLUDE directive does not work in this context because I need the output of the inclusion to be generated in situ.)

phg
  • 1,752
  • 1
  • 16
  • 30
  • Goro is right, you should describe what is your goal and it could be useful to someone to suggest you something more feasible and reasonable – Kiwy Sep 18 '18 at 12:07
  • @Kiwy: The objective is to know how to use ``$shell()`` in ``remind(1)`` to have its result parsed as calendar data. E. g. when ``/tmp/foo.rem`` is a valid reminder file, use ``$shell()`` to execute ``cat /tmp/foo.rem`` and have the output parsed by ``remind`` when it’s executed. – phg Sep 18 '18 at 12:11
  • @Goro “detailed explaination about functions uusage can be found in here tutorialspoint.com/unix/unix-shell-functions.htm” – how is that in any way related to ``remind``? – phg Sep 18 '18 at 12:12
  • 3
    @phg. Thank you! the point is that the question is not clear enough! In order to help you more efficiently, would you please revise the question and add more clarifications, this will help every reader in the future as will! –  Sep 18 '18 at 12:16
  • 2
    To "dereference" a variable in `remind`, you can use `[tmp]`. This does not seem to work when the variable contains a full `REM` command though. – Kusalananda Sep 18 '18 at 12:28

1 Answers1

5

Your problem is not with the shell() function, but

a) with the way you try to interpolate expressions/variables -- you should use [tmp] instead of $tmp

b) with the fact that remind doesn't allow MSG in expressions:

$ cat /tmp/foo.rem
SET var "REM Sep 13 2018 MSG test"
[var]
$ remind /tmp/foo.rem
/tmp/foo.rem(2): Can't nest MSG, MSF, RUN, etc. in expression
No reminders.

This is what the documentation says:

  o      You  cannot  use  expression-pasting to determine the type (MSG,
         CAL, etc.) of a REM command.  You can paste  expressions  before
         and  after  the  MSG, etc keywords, but cannot do something like
         this:
             REM ["12 Nov 1993 AT 13:05 " + "MSG" + " BOO!"]

I'm not a remind user, but this is my first crack at fixing your problem:

SET tmp shell("cat /tmp/test.rem", -1)
REM [substr(tmp, 4, index(tmp, "MSG")-1)] MSG [substr(tmp, index(tmp, "MSG")+4)]

provided that /tmp/test.rem is of the form REM ... MSG ....

Please notice that in remind, indexes start from 1, not from 0.

Note

If your problem is actually 'how to include dynamically generated content in a remind file', you may do that by redirecting the output of the shell command to a temporary file, then INCLUDE-ing that file:

INCLUDE [shell("echo REM " + today() + " MSG hello > /tmp/foo.rem; echo /tmp/foo.rem")]

Or you could use the INCLUDE command with a fifo instead of a regular file, and have a script that writes to the fifo each time it is opened.

Before starting reminder:

$ mkfifo /tmp/remind-fifo
$ while echo 'REM Sep 18 2018 MSG test' > /tmp/remind-fifo; do sleep 1; done &

Replace the echo with whatever script you need to generate the remind commands (eg. sh my_script > /tmp/remind-fifo).

Then, in the remind file, you can simply include the fifo:

INCLUDE /tmp/remind-fifo

The fifo approach could be used with other programs that have an include mechanism (eg. the C preprocessor)

  • Your first solution is as ingenious as it is impractical because the contents of that file is entire calendars from external sources. Parsing those with ``substr()`` is going to be awkward. – phg Sep 21 '18 at 07:19
  • Regarding the named pipe approach, that’s actually what I’m doing right now. Other alternatives I’ve thought of are writing a FUSE fs or monitoring changes on the source files with inotify. All of it seems overkill though. – phg Sep 21 '18 at 07:22
  • @phg I've added yet another trick that you've probably already tried, but which is not acceptable for reasons you don't deign to tell in your question. –  Sep 24 '18 at 13:41