{"id":26316768,"url":"https://github.com/casperklein/supervisor.sh","last_synced_at":"2026-05-20T03:34:24.709Z","repository":{"id":282502019,"uuid":"941663542","full_name":"casperklein/supervisor.sh","owner":"casperklein","description":"supervisor.sh is a lightweight Bash script for managing processes based on a YAML configuration file.","archived":false,"fork":false,"pushed_at":"2025-03-15T02:19:55.000Z","size":10,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-15T03:19:39.679Z","etag":null,"topics":["bash","process-manager"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/casperklein.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-03-02T20:09:39.000Z","updated_at":"2025-03-15T02:19:58.000Z","dependencies_parsed_at":"2025-03-15T03:19:42.392Z","dependency_job_id":"8351fb42-aa5c-489d-9b7c-1051a94de333","html_url":"https://github.com/casperklein/supervisor.sh","commit_stats":null,"previous_names":["casperklein/supervisor.sh"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/casperklein%2Fsupervisor.sh","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/casperklein%2Fsupervisor.sh/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/casperklein%2Fsupervisor.sh/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/casperklein%2Fsupervisor.sh/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/casperklein","download_url":"https://codeload.github.com/casperklein/supervisor.sh/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243732251,"owners_count":20338839,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bash","process-manager"],"created_at":"2025-03-15T13:16:43.887Z","updated_at":"2026-05-20T03:34:24.703Z","avatar_url":"https://github.com/casperklein.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cpicture\u003e\n    \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"assets/logo-dark.png\"\u003e\n    \u003cimg alt=\"\" src=\"assets/logo-light.png\"\u003e\n  \u003c/picture\u003e\n\u003c/div\u003e\n\n## Description\n\n`supervisor.sh` is a process supervisor inspired by [Supervisord](https://supervisord.org/) written in Bash.\nIt's a lightweight _almost pure_ Bash solution, providing basic functionality to supervise processes (called jobs). The configuration is done in a YAML configuration file. By default, all jobs are automatically started and, in case of an error (exit code \u003e 0), restarted.\n\nFor environments like a Docker container, where minimal overhead is desired, the dependency on `yq` can be removed by converting the YAML configuration to Bash.\n\n### Foreground mode\n\nWithout the explicit `start` command, `supervisor.sh` runs in the foreground. It can be stopped by:\n\n1. Pressing CTRL-C.\n2. Running `supervisor.sh stop` in another session.\n\n### Daemon mode\n\nTo run the supervisor in daemon mode, use `supervisor.sh start`.\n\n## Dependencies\n\n- Bash \u003e= 5.1\n- [yq](https://github.com/mikefarah/yq) - a lightweight and portable command-line YAML processor\n- The following core utilities: cat mkdir readlink rm setsid sleep tail\n\nThe `yq` dependency can be removed. See [below](#run-without-the-yq-dependency).\n\n## Installation\n\n```bash\nSV_VERSION=0.14\n\n# Supervisor\ncurl -sSLf -o /usr/bin/supervisor.sh \"https://raw.githubusercontent.com/casperklein/supervisor.sh/refs/tags/$SV_VERSION/supervisor.sh\"\nchmod +x /usr/bin/supervisor.sh\n\n# Bash completion (optional)\ncurl -sSLf -o /etc/bash_completion.d/supervisor.sh \"https://raw.githubusercontent.com/casperklein/supervisor.sh/refs/tags/$SV_VERSION/supervisor-completion.bash\"\n```\n\n## Usage\n\n```text\nUsage:\n  supervisor.sh [OPTION] [COMMAND]\n\nConfiguration file:\n  By default, the configuration is read from '/etc/supervisor.yaml'.\n  If 'yq' is not available, '/etc/supervisor.yaml.sh' will be used instead.\n  Provide '--config' to specify a custom configuration file.\n\nOptions:\n  -c, --config     Specify configuration file, e.g. 'supervisor.sh -c /path/config.yaml'.\n  -h, --help       Show this help.\n  -n, --no-color   Disable color usage.\n  -v, --version    Show version.\n\nCommands:\n  start            Start supervisor.sh as daemon.\n  start \u003cjob\u003e      Start job.\n  stop             Stop supervisor.sh.\n  stop  \u003cjob\u003e      Stop job.\n  restart          Restart daemon.\n  restart \u003cjob\u003e    Restart job.\n  status           Show process states.\n  fix              Fix unclean shutdown.\n  lint             Validate and display the full configuration, including implicit default values.\n  log              Show continuously the supervisor.sh log (only for daemon mode)\n  logs             Show continuously the supervisor.sh log + job logs.\n  convert          Convert the YAML configuration file to Bash.\n                   This allows the usage without the 'yq' dependency.\n\nIf no command is provided, supervisor.sh will start in foreground.\n```\n\n## Configuration file (`supervisor.yaml`)\n\nBy default, the configuration is read from `/etc/supervisor.yaml`. You can specify another location with the `--config` option.\n\n### supervisor\n\nKey                    | Required | Default             | Possible Values      | Description\n-----------------------|----------|---------------------|----------------------|------------------------------------------------------------------------------------------------\n`logfile`              | No       | `/dev/stdout`       | Valid file path      | Log file for supervisor output (only for daemon mode)\n`sigterm_grace_period` | No       | `10`                | Any number           | Grace period in seconds until SIGKILL is sent to processes that keeps running after SIGTERM.\n`keep_running`         | No       | `off`               | `on`, `off`          | Exit supervisor when all jobs are stopped (`off`) or keep running (`on`).\n`color`                | No       |                     | `\"\\e[0;34m\"` (blue)  | Text color defined as [escape sequence](https://gist.github.com/JBlond/2fea43a3049b38287e5e9cefc87b2124) for terminal colors (only foreground mode).\n`color_error`          | No       | `\"\\e[1;31m]\"` (red) | `\"\\e[0;32m\"` (green) | Text color for errors defined as [escape sequence](https://gist.github.com/JBlond/2fea43a3049b38287e5e9cefc87b2124) for terminal colors (only foreground mode).\n`time_format`          | No       | `%F %T`             | `strftime` format    | Time format that is used for status messages. See [`strftime`](https://linux.die.net/man/3/strftime) for possible values.\n\n### jobs\n\nKey             | Required | Default       | Possible Values      | Description\n----------------|----------|---------------|----------------------|------------------------------------------------------------------------------------------\n`name`          | Yes      |               | Any string           | Job name\n`command`       | Yes      |               | Any string           | Job command\n`autostart`     | No       | `on`          | `on`, `off`          | Start the job automatically (`on`) or not (`off`).\n`logfile`       | No       | `/dev/stdout` | Valid file path      | Write output to log file.\n`restart`       | No       | `error`       | `error`, `on`, `off` | Restart the job if it exits, only on failure (`error`) or always (`on`) or never (`off`).\n`restart_limit` | No       | `3`           | Any positive integer | Restart the job only n times. Set 0 for unlimited restarts.\n`required`      | No       | `no`          | `no`, `yes`          | When a required job terminates, all remaining jobs and `supervisor.sh` are stopped as well.\n\n## Example\n\n```yaml\nsupervisor:\n  logfile: \"/var/log/supervisor.log\"\n  sigterm_grace_period: 10\n  keep_running: \"off\"\n  color: \"\\e[0;34m\" # blue text color\n\njobs:\n  - name: \"job1-restart\"\n    command: \"echo 'Job 1: I will fail in 4 seconds. But supervisor will restart me 3 times.'; sleep 4; exit 1\"\n    autostart: \"on\"\n    restart: \"error\"\n\n  - name: \"job2-no-restart\"\n    command: \"echo 'Job 2: No restart for me on failure in 3 seconds.'; sleep 3; exit 1\"\n    restart: \"off\"\n\n  - name: \"job3-no-autostart\"\n    command: \"echo 'Job 3: I was started manually'\"\n    autostart: \"off\"\n    logfile: \"/var/log/job3.log\"\n\n  - name: \"job4-required\"\n    command: \"echo 'Job 4: I am required. When I stop in 20 seconds, supervisor will stop too.'; sleep 20\"\n    restart: \"off\"\n    required: \"yes\"\n\n  - name: \"job5-ignore-SIGTERM\"\n    command: \"trap true SIGTERM; echo 'Job 5: I will ignore SIGTERM.'; while :; do sleep 1d; done\"\n```\n\n## Bash completion\n\nIf you have [`bash-completion`](https://github.com/scop/bash-completion) installed, simply copy `supervisor-completion.bash` to `/etc/bash_completion.d/`.\n\nOtherwise, you can source `supervisor-completion.bash` in your `.bashrc`.\n\n## Run without the 'yq' dependency\n\nIf you want to remove the `yq` dependency, you can convert the YAML configuration to Bash. This conversion must be done in an environment where `yq` is available.\n\n```bash\nsupervisor.sh -c /etc/supervisor.yaml convert\n\n# Now you can use supervisor.sh without the 'yq' dependency\nsupervisor.sh -c /etc/supervisor.yaml.sh \u003ccommand\u003e\n```\n\n### Convert using Docker\n\n```bash\ndocker run --rm -v \"${PWD}\":/workdir -u root --entrypoint /bin/sh mikefarah/yq -c \"apk add bash; bash -c './supervisor.sh -c supervisor.yaml convert'\"\n```\n\n## Demo / Tests\n\nSee `supervisor.sh` in action [here](assets/demo.gif) and [here](assets/demo-docker.gif).\n\nYou can also run the demo locally using `tests/run-tests.sh` or `tests/run-tests-docker.sh`. This will:\n\n- Run some `yq` tests\n- Print system environment information\n- Start `supervisor.sh` with an [example](https://github.com/casperklein/supervisor.sh/blob/master/tests/supervisor.yaml) configuration.\n\nThis includes 4 jobs:\n\n1. parent.sh: A simple bash script that starts a child process (`child.sh`) and then does nothing. When the TERM signal is received, the script terminates. When `child.sh` receives the TERM signal, it will be ignored. When `supervisor.sh` stops this job, it takes care, that the whole process group has terminated. Since child.sh ignores the TERM signal, the process will be killed (SIGKILL) after a grace period.\n\n2. fail.sh: A simple bash script, that fails after 3 seconds. This job will be restarted 2 times on failure. On the third failure, `supervisor.sh` terminates, because the job is configured as _required_.\n\n3. sleep: This job just sleeps for 1 day.\n\n4. prefix: This jobs demonstrated, how to prefix a job output with the current date/time (this can easily match the `time_format` that `supervisor.sh` uses).\n\n## Custom PID directory\n\nBy default, `/run/supervisor.sh` is used for storing files needed at runtime. To use another location, you can set the environment variable `PID_DIR`.\n\n```bash\nPID_DIR=/home/alice/supervisor.sh supervisor.sh start\n```\n\nThis is useful when `supervisor.sh` runs rootless.\n\n## Used by these projects\n\n- [Pi-hole for Home Assistant](https://github.com/casperklein/homeassistant-addons/blob/master/pi-hole/README.md)\n- [docker-smokeping](https://github.com/casperklein/docker-smokeping)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcasperklein%2Fsupervisor.sh","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcasperklein%2Fsupervisor.sh","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcasperklein%2Fsupervisor.sh/lists"}