{"id":18828430,"url":"https://github.com/dealfonso/bashc","last_synced_at":"2025-10-29T12:03:10.883Z","repository":{"id":118337537,"uuid":"144445714","full_name":"dealfonso/bashc","owner":"dealfonso","description":"A simple framework ease developing of bash applications","archived":false,"fork":false,"pushed_at":"2022-06-08T12:16:00.000Z","size":87,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-22T14:12:41.871Z","etag":null,"topics":["bash","bash-hacks","bash-scripting","packaging-tool"],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dealfonso.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2018-08-12T07:09:24.000Z","updated_at":"2022-06-08T12:16:04.000Z","dependencies_parsed_at":null,"dependency_job_id":"68a9c767-69ba-4dc7-80a6-5ee0aa3df76c","html_url":"https://github.com/dealfonso/bashc","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/dealfonso/bashc","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dealfonso%2Fbashc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dealfonso%2Fbashc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dealfonso%2Fbashc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dealfonso%2Fbashc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dealfonso","download_url":"https://codeload.github.com/dealfonso/bashc/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dealfonso%2Fbashc/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265738206,"owners_count":23820156,"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","bash-hacks","bash-scripting","packaging-tool"],"created_at":"2024-11-08T01:25:08.108Z","updated_at":"2025-10-29T12:03:10.562Z","avatar_url":"https://github.com/dealfonso.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# bashc\nA simple framework to ease the development of bash applications.\n\nOther programming languages (e.g. python, perl, C, etc.) have libraries that ease common tasks. bashc is a framework that enables to have **libraries of bash functions** instead of forcing the programmer to develop ad-hoc solutions. These libraries can be used in your bash scripts, by including them in common bash scripts, and _somehow compiling_ the scripts into a **re-distributable and library independent** one.\n\n**What includes**\n- For **code re-usage**, a library of **common functions** in bash (e.g. `is_int`, parameter parsing, `readconffile`, `trim`, `in_list`, etc.).\n- To **ease re-distribution**, a _compiler-like_ application that makes a **single bash script** out of multiple scripts that are included using the `source` statement.\n- To **reduce the size** of the scripts, a _removal of unused functions_ tool that enables to include all the libraries, but only redistribute those functions that are used.\n- To create **packages for re-distribution**, `bashcbuild` that is a package builder that eases the **creation of simple rpm and deb packages**.\n- To **ease starting a new application**, `bashcgen` that is an application that creates a new application from a template folder (including a customizable folder tree, customizable files, etc.).\n\nThe functions work for the library, but also for any other bash script. So, you can use applications such as `bashc`, `bashcbuild` and `bashcgen` but not use any function in the library. E.g. you can create your own library of functions and use `bashc` to generate a single script and to remove the unused functions, or you can create your own template for `bashcgen` to create (e.g.) _NodeJS_ base applications.\n\n## Installing\n\nYou can get `bashc` in source form, or in one of the [packages](https://github.com/dealfonso/bashc/releases).\n\n### Packages\n\n**Ubuntu**\n\n```\n$ apt install -y ./bashc_0.9-rc1.deb\n$ bashc --version\n0.9-rc1\n```\n\n**CentOS**\n\n```\n$ yum install -y ./bashc-0.9-rc1.noarch.rpm\n$ bashc --version\n0.9-rc1\n```\n\n\u003e This version do not support the creation of deb packages. You can use [FPM](https://github.com/jordansissel/fpm) to create the deb package from the rpm package.\n\n**Other distro**\n```\n$ tar xfz bashc_0.9-rc1.tar.gz -C / --strip-components=1\n$ bashc --version\n0.9-rc1\n```\n\n\u003e In this case, you will need to solve the dependencies.\n\n### Source\n\nUse the code without the need of installing:\n\n```\n$ git clone https://github.com/dealfonso/bashc\n$ cd bashc\n$ ./bashc --version\n0.9-rc1\n```\n\n## Why `bashc`?\n\nbash scripting is a powerful language to develop **applications that manage servers**, but also to **automate processes** in Linux, to execute **batch tasks**, or to other tasks that can be executed in the **Linux commandline** e.g. implement workflows in scientific applications (processing the output from one application to prepare it for other application).\n\nThe **immediate use of bash scripting is to automate scripts**, but there are a lot of applications and **tools in the commandline that are powerful** enough and easy to use to have the need to use other languages such as _python_, _perl_, etc. that will have harder to learn just to implement workflows of other tools. \n\nWhen you start accepting parameters in the commandline, and you want to make checks of the results (to create better tools), etc. **you need common functions** as the other languages have.\n\n**bashc** solves that problem by enabling to have **libraries of bash functions** that can be re-used in your bash scripts.\n\n**Example of a typical bash script**\n```\n#!/bin/bash\nexecute_app \u003e myoutput\nsed -i 's/.../g' myoutput\nRESULT=`execute_otherapp \u003c myoutput`\necho $RESULT\n...\n```\n\nThe problem happens when you need to get options from the commandline, sanitize these options, make checks between in the outputs, etc.\n\n**Example of the same script with parameters**\n```\n#!/bin/bash\nwhile [ $# -gt 0 ]; do\n  case $1 in\n    --debug|-d)   DEBUG=1;;\n    --output|-o)  shift\n                  OUTPUTFILE=$1;;\n    *)  echo \"error\" \u003e\u00262\n        exit 1;;\n  esac\n  shift\ndone\nexecute_app \u003e $OUTPUTFILE\nsed -i 's/.../g' $OUTPUTFILE\nRESULT=`execute_otherapp \u003c $OUTPUTFILE`\nif [[ \"$1\" =~ ^[+-]{0,1}[0-9]+$ ]]; then\n  echo \"the result is a number\"\nelse\n  echo \"error\"\nfi\n```\n\n\u003e Using that script you cannot manage parameters constructions such as `-do \u003couput file\u003e`.\n\n**Example of the same script using bashc**\n```\n#!/bin/bash\nsource all.bashc\n\nbashc.parameters_start\nwhile bashc.parameters_next; do\n  PARAM=\"$(bashc.parameters_current)\"\n  case \"$PARAM\" in\n    --debug|-d)   DEBUG=1;;\n    --output|-o)  shift\n                  OUTPUTFILE=$1;;\n    *)            usage \u0026\u0026 bashc.finalize 1 \"invalid parameter $PARAM\";;\n  esac\ndone\n\nexecute_app \u003e $OUTPUTFILE\nsed -i 's/.../g' $OUTPUTFILE\nRESULT=`execute_otherapp \u003c $OUTPUTFILE`\n\nif is_int \"$RESULT\"; then\n  echo \"the result is a number\"\nelse\n  echo \"error\"\nfi\n```\n\nThe ad-hoc bash script is **hard to read for maintaining the code**. E.g. what means `[[ \"$1\" =~ ^[+-]{0,1}[0-9]+$ ]]`? Or how can I implement parameters constructions such as `-do \u003couput file\u003e`?\n\nThe bashc script is easier to understand and **easier to maintain** in the future.\n\n## Use case\n\nWe'll start a new application using `bashcgen`...\n\n```\nroot@95b847d5cbaa:~# bashcgen myapp\napplication myapp created in folder ./myapp\nroot@95b847d5cbaa:~# cd myapp/\nroot@95b847d5cbaa:~/myapp# ls -l\ntotal 16\ndrwxr-xr-x 3 root root 4096 Sep  6 12:42 etc\n-rwxr-xr-x 1 root root 2349 Sep  6 12:42 myapp.bashc\n-rw-r--r-- 1 root root  488 Sep  6 12:42 myapp.bashcbuild\n-rw-r--r-- 1 root root   13 Sep  6 12:42 version\n```\n\nThe code for the new app is the next:\n```bash\n#!/bin/bash\nfunction usage() {\n  cat \u003c\u003cEOF\n\nThis is a template for a bash application\n\nmyapp \u003cappname\u003e\n\n  --version | -V            Shows the version number and finalizes.\n  --verbose | -v            Shows more information about the procedure.\n  --debug                   Shows a lot more information about the procedure.\n  --help | -h               Shows this help and exits.\nEOF\n}\n\nfunction verify_dependencies() {\n  if false; then\n    bashc.finalize 1 \"dependency failed\"\n  fi\n}\n\n# The list of default configuration files (it is set here just in case that you want to change it in the commandline)\nCONFIGFILES=\"/etc/default/myapp.conf /etc/myapp/myapp.conf /etc/myapp.conf $HOME/.myapp etc/myapp.conf etc/myapp/myapp.conf\"\n\n# The basic include than gets all from bashc (you should use -S flag to remove the unused functions)\nsource all.bashc\n\n# A include for the version of this application\nsource version\n\n# Parse the commandline into an array\nbashc.parameter_parse_commandline \"$@\"\n\nbashc.parameters_start\nwhile bashc.parameters_next; do\n  PARAM=\"$(bashc.parameters_current)\"\n  case \"$PARAM\" in\n    --verbose|-v)           VERBOSE=true;;\n    --debug)                DEBUG=true;;\n    --help | -h)            usage \u0026\u0026 bashc.finalize;;\n    --version|-V)           p_out \"$VERSION\"\n                            bashc.finalize 0;;\n    *)                      usage \u0026\u0026 bashc.finalize 1 \"invalid parameter $PARAM\";;\n  esac\ndone\n\n# You should check this function to include the checks for the dependencies of your bash application\nverify_dependencies\n\n# Read the variables from the configuration files\nbashc.readconffiles \"$CONFIGFILES\" VAR_myapp\n\n# Now you have to implement your app\np_out \"wellcome to myapp, I got the value ${VAR_myapp} for var VAR_myapp from the config file\"\n```\n\nThe application is fully working, but by now you need to run it using `bashc`:\n\n```\nroot@95b847d5cbaa:~/myapp# ./myapp.bashc \n./myapp.bashc: line 43: all.bashc: No such file or directory\n./myapp.bashc: line 49: bashc.parameter_parse_commandline: command not found\n./myapp.bashc: line 51: bashc.parameters_start: command not found\n./myapp.bashc: line 52: bashc.parameters_next: command not found\n./myapp.bashc: line 68: bashc.readconffiles: command not found\n./myapp.bashc: line 71: p_out: command not found\nroot@95b847d5cbaa:~/myapp# bashc myapp.bashc --version\n0.0-0\n```\n\nThe application is even able to read variables from its config file\n\n```\nroot@95b847d5cbaa:~/myapp# bashc myapp.bashc\nwellcome to myapp, I got the value false for var VAR_myapp from the config file\n```\n\nNow you can \"compile\" the application into a single independent script, and then the application will be independent from `bashc`:\n\n```\nroot@95b847d5cbaa:~/myapp# bashc -cS myapp.bashc -o myapp\nroot@95b847d5cbaa:~/myapp# chmod +x myapp\nroot@95b847d5cbaa:~/myapp# ./myapp\nwellcome to myapp, I got the value false for var VAR_myapp from the config file\n```\n\n## Building packages with `bashcbuild`\nSometimes you have very simple pieces of code that are likely to be re-distributed. The structure of the code is very simple, but if you want to create deb or rpm packages, you need to learn the structure of them\n\n`bashcbuild` is a very straightforward package builder that is suitable for simple packages such as those that consist in bash scripts.\n\n**example**\n\nto create a package that has a /etc/myapp/myapp.conf and a binary that is located in /usr/bin/myapp, you simply have to create the next file:\n\n```\nPACKAGE=myapp\n/etc/$PACKAGE/;etc/myapp/myapp.conf\n/usr/bin/;myapp\n```\n\nAnd run the next command:\n\n```\n# bashcbuild myapp.bashcbuild --deb --rpm\n[WARNING]  2018.09.06-14:09:36 information about version not included (i.e. VERSION variable in package descriptor). Using 0.0 as the version number.\n/root/myapp/myapp_0.0-0.tar.gz successfully created\n/root/myapp/myapp-0.0-0.noarch.rpm successfully created\n/root/myapp/myapp_0.0-0.deb successfully created\n```\n\nThen you can verify the contents of the packages:\n\n```\n$ tar tf myapp_0.0-0.tar.gz \nmyapp-0.0/\nmyapp-0.0/etc/\nmyapp-0.0/etc/myapp/\nmyapp-0.0/etc/myapp/myapp.conf\nmyapp-0.0/usr/\nmyapp-0.0/usr/bin/\nmyapp-0.0/usr/bin/myapp\n$ dpkg-deb -c myapp_0.0-0.deb \ndrwxr-xr-x root/root         0 2018-09-06 14:09 ./\ndrwxr-xr-x root/root         0 2018-09-06 14:09 ./etc/\ndrwxr-xr-x root/root         0 2018-09-06 14:09 ./etc/myapp/\n-rw-r--r-- root/root        87 2018-09-06 14:09 ./etc/myapp/myapp.conf\ndrwxr-xr-x root/root         0 2018-09-06 14:09 ./usr/\ndrwxr-xr-x root/root         0 2018-09-06 14:09 ./usr/bin/\n-rwxr-xr-x root/root      8711 2018-09-06 14:09 ./usr/bin/myapp\n$ rpm -qlp ./myapp-0.0-0.noarch.rpm \n/etc/myapp/myapp.conf\n/usr/bin/myapp\n```\n\n# Library\n\nThe functions that are included in the library\n**(list in progress)**\n\n**Configuration files**\n- `bashc.readconf` reads configuration variables from a string and exports them. Supports quotes and double quoted parameters, comments, etc.\n- `bashc.readconffile` reads configuration variables from a file (see also `bashc.readconf`).\n- `bashc.readconffiles` reads configuration variables from a set of files (see also `bashc.readconf` and `bashc.readconffile`).\n- `bashc.cleanvalue` reads the value for a variable from a string.\n\n**Logging and output**\n- `p_out`: outputs a string to the stdout (as is).\n- `p_debug`: outputs a string to stderr and tags it with the timestamp as debug info (if _DEBUG_ var is set to true).\n- `p_error`: outputs a string to stderr and tags it with the timestamp as error info.\n- `p_warning`: outputs a string to stderr and tags it with the timestamp as warning info.\n- `p_info`: outputs a string to stderr and tags it with the timestamp as verbose info (if _DEBUG_ or _VERBOSE_ vars are set to true).\n- `p_mute`: mutes debug, warning, etc. info that fulfil a regular expressions.\n- `p_errfile`: outputs a string to stderr or to the file in LOGFILE variable.\n- `bashc.set_logger`: sets the prepended string to `p_*` functions.\n- `bashc.push_logger`: adds a logger info to the prepended info to the `p_*` functions.\n- `bashc.pop_logger`: remove a logger info to the prepended info to the `p_*` functions.\n- `bashc.finalize`: finalizes the execution of the current script, with an error code and (optional) outputs some information.\n\n**Parameter parsing**\n- `bashc.parameter_parse_commandline`: prepares the commandline to be parsed.\n- `bashc.parameters_start`: goes to the first parameter.\n- `bashc.parameters_next`: advances to the next parameter.\n- `bashc.parameters_end`: checks whether there are more parameters or not.\n- `bashc.parameters_current`: returns the current parameter.\n\n**Temporary files**\n- `bashc.tempfile`: creates a temporary file.\n- `bashc.tempdir`: creates a temporary folder.\n\n**Utility functions**\n- `bashc.trim`: remove leading and trailing blank spaces from a string.\n- `bashc.ltrim`: remove leading blank spaces from a string.\n- `bashc.rtrim`: remove trailing blank spaces from a string\n- `bashc.build_cmdline`: builds a quoted commandline from the parameters to the function.\n- **deprecated** `bashc.dump_list`: (please use `bashc.dump_in_lines`) dumps the list of parameters and prepends its position.\n- `bashc.parameters_to_list`: converts a set of parameters to the function, to an array.\n- `bashc.list_append`: adds a value to the end of an array.\n- `bashc.in_list`: checks whether a value is in an array or not.\n- `bashc.is_int`: checks if a string is a integer.\n- `bashc.arrayze_cmd`: creates an array of parameters from a commandline string.\n- `bashc.lines_to_array`: converts a set of lines to an array.\n- `bashc.cleanfile`: removes blank lines, bash-like comments, trailing and leading spaces from a string.\n- `bashc.dump_in_lines`: dumps the list of parameters and prepends its position.\n- `bashc.dump_vars`: dumps the value of the variables passed as parameters.\n- `bashc.expand_ranges`: expand ranges in strings such as `myrange[0-2]` into `myrange0, myrange1, myrange2` (it also support ranges of characters and reverse order).","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdealfonso%2Fbashc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdealfonso%2Fbashc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdealfonso%2Fbashc/lists"}