#command-line #rest #schedule #executor #execute-command #status-command

app scheduledexec

REST service to execute series of command lines at specific moments of time

1 unstable release

0.1.0 Feb 7, 2024

#131 in HTTP server

39 downloads per month


362 lines


REST service to execute command lines at appropriate moments using POST requests and monitor status of those commands.


  • Executing command lines supplied by REST client at relative moments of time specified in the scenario
  • Collecting and reporting outputs and timing of the commands
  • Ability to prepend a program name to the command line array (to avoid giving access to the whole shell)
  • Flexible server socket listening options (e.g. UNIX socket or systemd socket-initation)


  • No support for non-UTF8 command line chunks or outputs
  • Unsuccessful commands abort scenarios
  • If command takes too long to execute and scheduledexec missed the next command, scenario is also aborted error


Here is a short list of endpoints:

/start - begin executing a scenario
/abort - abort currenty executed scenario
/status - query information
/monitor - subscribe to events     
/getscenario - get current or last scenario
/report - download final scenario report

You can use OpenAPI editor like Swagger with a pre-built openapi.json file to see the documentation.


$ cargo run  --
$ curl; echo
$ curl -H 'Content-Type: application/json' -d @scenario_sample.json -s
$ curl; echo
$ curl; echo
{"error":false,"aborted":false,"entries":[{"out":"Wed Feb  7 22:44:24 CET 2024\n","err":"","exitcode":0,"timespan_ms":3},...]}


Download a pre-built executable from Github releases or install from source code with cargo install --path . or cargo install scheduledexec.

CLI options

scheduledexec --help output
REST service to execute series of command lines at specific moments of time


          Socket address to listen for incoming connections.
          Various types of addresses are supported:
          * TCP socket address and port, like or [::]:80
          * UNIX socket path like /tmp/mysock or Linux abstract address like @abstract
          * Special keyword "inetd" for serving one connection from stdin/stdout
          * Special keyword "sd-listen" or "sd-listen-unix" to accept connections from file descriptor 3 (e.g. systemd socket activation)

          Prepend this command to all executed chunks

          remove UNIX socket prior to binding to it

      --unix-listen-chmod <UNIX_LISTEN_CHMOD>
          change filesystem mode of the newly bound UNIX socket to `owner`, `group` or `everybody`

      --unix-listen-uid <UNIX_LISTEN_UID>
          change owner user of the newly bound UNIX socket to this numeric uid

      --unix-listen-gid <UNIX_LISTEN_GID>
          change owner group of the newly bound UNIX socket to this numeric uid

          ignore environment variables like LISTEN_PID or LISTEN_FDS and unconditionally use file descritor `3` as a socket in sd-listen or sd-listen-unix modes

      --tcp-keepalive <TCP_KEEPALIVE>
          set SO_KEEPALIVE settings for each accepted TCP connection.
          Value is a colon-separated triplet of time_ms:count:interval_ms, each of which is optional.

          Try to set SO_REUSEPORT, so that multiple processes can accept connections from the same port in a round-robin fashion

      --recv-buffer-size <RECV_BUFFER_SIZE>
          Set socket's SO_RCVBUF value

      --send-buffer-size <SEND_BUFFER_SIZE>
          Set socket's SO_SNDBUF value

          Set socket's IPV6_V6ONLY to true, to avoid receiving IPv4 connections on IPv6 socket

      --tcp-listen-backlog <TCP_LISTEN_BACKLOG>
          Maximum number of pending unaccepted connections

  -h, --help
          Print help (see a summary with '-h')


~260K SLoC