{"id":27854866,"url":"https://github.com/genaker/basher","last_synced_at":"2026-02-19T13:02:16.914Z","repository":{"id":282781979,"uuid":"949633876","full_name":"Genaker/Basher","owner":"Genaker","description":null,"archived":false,"fork":false,"pushed_at":"2026-02-12T08:45:56.000Z","size":139,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-12T17:46:58.858Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","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/Genaker.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,"zenodo":null}},"created_at":"2025-03-16T21:49:12.000Z","updated_at":"2026-02-12T08:46:00.000Z","dependencies_parsed_at":"2025-03-16T23:11:39.483Z","dependency_job_id":"6971458c-5d78-48df-9ee8-97dd1ddcbe60","html_url":"https://github.com/Genaker/Basher","commit_stats":null,"previous_names":["genaker/basher"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Genaker/Basher","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Genaker%2FBasher","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Genaker%2FBasher/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Genaker%2FBasher/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Genaker%2FBasher/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Genaker","download_url":"https://codeload.github.com/Genaker/Basher/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Genaker%2FBasher/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29614591,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-19T10:52:55.328Z","status":"ssl_error","status_checked_at":"2026-02-19T10:52:26.323Z","response_time":117,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":[],"created_at":"2025-05-04T09:59:33.564Z","updated_at":"2026-02-19T13:02:16.905Z","avatar_url":"https://github.com/Genaker.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Basher\n\nBasher is a Python library that provides a convenient wrapper around common bash commands, making it easier to perform file system operations, package management, and archive handling in Python scripts. Basher can also be used to build Docker images and used in Dockerfiles.\n\n## Quick start\n\n```bash\n# Install from PyPI\npip3 install basher2\n\n# Or install from repo (for development)\ncd Basher \u0026\u0026 pip3 install -e .\n\n# Run tests\npython3 -m pytest tests/ -v\n```\n\n## Project structure\n\n```\nBasher/\n├── basher/           # Library source\n├── install-oro.py    # OroCommerce install script\n├── install-magento.py\n├── tests/            # pytest tests\n├── tests.py          # legacy tests\n├── docker-compose.yml\n├── Dockerfile\n└── docs/\n```\n\n## Philosophy\n\n**When Python is used instead of shell commands, the output must match the Linux command analog—so that copying the output allows reproduction without Python.** See [docs/PHILOSOPHY.md](docs/PHILOSOPHY.md) for the full design principles.\n\n# Why Python for Bash\n\nPython is a great choice for tasks that you might otherwise do in a Bash script for several reasons:\n\n## Readability and Maintainability\n\nPython’s syntax is often more readable and less prone to subtle errors compared to complex Bash one-liners.\nIt’s easier for teams (especially those less familiar with shell scripting) to understand and maintain Python scripts.\n\n## Large Standard Library\n\nPython has built-in support for common tasks like working with files, directories, CSV or JSON data, HTTP requests, etc.\nIn Bash, you often need external utilities (like awk, sed, curl, etc.) or rely on multiple commands piped together.\n\n## Portability\n\nPython is available on most modern systems, including Linux, macOS, and Windows.\nComplex Bash scripts can run into portability issues when you use commands or shell features that differ across Unix-like systems.\n\n## Error Handling and Debugging\n\nPython’s exception handling is more robust and easier to manage compared to handling exit codes and conditional branching in Bash.\nPython’s built-in debugger (pdb) can step through code, making it simpler to diagnose and fix problems.\n\n## Scaling Complexity\n\nAs your script grows, Python can handle more advanced logic, data structures, and third-party libraries with ease.\nBash scripts become harder to read and maintain once they get beyond trivial tasks.\n\n## Better for String Manipulation and Data Parsing\n\nPython excels at parsing logs, JSON, XML, CSV, and other data formats with minimal hassle.\nIn Bash, such tasks quickly get messy, often requiring multiple external tools.\n\n## Easier Interfacing with Other Systems\n\nWhether you need to interact with databases, perform network calls, or handle complex file I/O, Python provides a straightforward approach.\nWhile Bash can call these tools, chaining them together can be more cumbersome.\n\n## Features\n\n- **File Operations**: Read, write, copy, move, and find files\n- **System Operations**: Install packages, create directories, change permissions\n- **Archive Operations**: Create and extract archives, compress and decompress files\n- **Command Execution**: Run bash commands with proper error handling\n- **Colorful Output**: Display messages in different colors for better visibility\n- **Interactive Mode**: Interactive mode for easy configuration of the script\n- **No Interaction Mode**: No interaction mode for easy installation of the script\n- **Detect Package Manager**: Detect the system's package manager\n\n## Compilation to bash script\n\nBy design, Basher is a Python library; however, it can be compiled into a Bash script, with each command acting as a straightforward Python wrapper in pure Bash.\n\n# Methodology\n\nOne Core Basher method is to use `bash.cmd` to execute commands. This method is a wrapper around the `bash` command and is the most straightforward way to execute commands. \n\nIn our implementation we wraping one logical server configuration into one method using basher core commands.\n\nForexample:\nInstall git and configure it\n```python\ndef install_git():\n    bash.echo(\"Installing git\")\n    bash.install(\"git\")\n    bash.cmd(\"git config --global user.name 'John Doe'\")\n    bash.cmd(\"git config --global user.email 'john.doe@example.com'\")\n```\n\nInstall nginx\n```python\ndef install_nginx():\n    bash.echo(\"Installing nginx\")\n    bash.install(\"nginx\")\n```\n\nInstall php\n```python\ndef install_php():\n    bash.echo(\"Installing php\")\n    bash.install(\"php\")\n```\n\nInstall mysql\n```python\ndef install_mysql():\n    bash.echo(\"Installing mysql\")\n    bash.install(\"mysql\")\n```\n\nInstall redis\n```python\ndef install_redis():\n    bash.echo(\"Installing redis\")\n    bash.install(\"redis\")\n```\n\nInstall postgresql\n```python\ndef install_postgresql():\n    bash.echo(\"Installing postgresql\")\n    bash.install(\"postgresql\")\n```\n\nInstall elasticsearch\n```python\ndef install_elasticsearch():\n    bash.echo(\"Installing elasticsearch\")\n    bash.install(\"elasticsearch\")\n```\n\nInstall node.js\n```python\ndef install_nodejs():\n    bash.echo(\"Installing node.js\")\n    bash.install(\"nodejs\")\n    bash.install(\"npm\")\n    bash.cmd(\"npm install -g yarn\")\n```\n\nInstall docker\n```python\ndef install_docker():\n    bash.echo(\"Installing docker\")\n    bash.install(\"docker\")\n    bash.cmd(\"docker --version\")\n    bash.echo(\"Installing docker compose\")\n    bash.install(\"docker-compose\")\n```\n\nInstall elasticsearch\n```python\ndef install_elasticsearch():\n    bash.echo(\"Installing elasticsearch\")\n    bash.install(\"elasticsearch\")\n```\n\nInstall composer for php\n```python\ndef install_composer():\n    bash.cmd(\"php -r \\\"copy('https://getcomposer.org/installer', 'composer-setup.php');\\\"\")\n    bash.cmd(\"php composer-setup.php\")\n    bash.cmd(\"php -r \\\"unlink('composer-setup.php');\\\"\")\n    bash.cmd(\"mv composer.phar /usr/bin/composer\")\n    bash.cmd(\"composer --version\")\n    bash.echo(\"Composer installed\")\n```\n\n# Complex Installation Example\n\nHere's an example of a complex installation using Basher, divided into logical methods:\n\n```python\ndef setup_web_server():\n    bash.echo(\"Setting up web server environment\")\n    install_nginx()\n    install_php()\n    install_mysql()\n    configure_nginx_for_php()\n    bash.echo(\"Web server environment setup complete\")\n\ndef install_nginx():\n    bash.echo(\"Installing Nginx\")\n    bash.install(\"nginx\")\n    bash.cmd(\"systemctl start nginx\")\n    bash.cmd(\"systemctl enable nginx\")\n\ndef install_php():\n    bash.echo(\"Installing PHP\")\n    bash.install(\"php-fpm\")\n    bash.install(\"php-mysql\")\n\ndef install_mysql():\n    bash.echo(\"Installing MySQL\")\n    bash.install(\"mysql-server\")\n    bash.cmd(\"systemctl start mysql\")\n    bash.cmd(\"systemctl enable mysql\")\n\ndef configure_nginx_for_php():\n    bash.echo(\"Configuring Nginx to use PHP\")\n    bash.write_to_file(\"/etc/nginx/sites-available/default\", \"\"\"\n    server {\n        listen 80;\n        server_name example.com;\n        root /var/www/html;\n\n        index index.php index.html index.htm;\n\n        location / {\n            try_files $uri $uri/ =404;\n        }\n\n        location ~ \\.php$ {\n            include snippets/fastcgi-php.conf;\n            fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;\n        }\n\n        location ~ /\\.ht {\n            deny all;\n        }\n    }\n    \"\"\")\n    bash.cmd(\"systemctl restart nginx\")\n```\n\n## Usage\n\n### Basic Usage\n\n```python\nfrom basher import Basher\n\n# Create a Basher instance\nbash = Basher()\n\n# Execute a shell command\noutput = bash.cmd(\"ls -la\")\n\n# Write to a file\nbash.write_to_file(\"/path/to/file.txt\", \"Hello, world!\")\n\n# Read from a file\ncontent = bash.read_file(\"/path/to/file.txt\")\n\n# Check if a file exists\nif bash.exists(\"/path/to/file.txt\"):\n    print(\"File exists!\")\n```\n\n### File Operations\n\n```python\n# Copy a file\nbash.copy(\"/source/file.txt\", \"/destination/file.txt\")\n\n# Move a file\nbash.mv(\"/source/file.txt\", \"/destination/file.txt\")\n\n# Find files matching a pattern\nfiles = bash.find(\"/search/directory\", \"*.txt\")\n\n# Check if a string exists in a file\nif bash.string_in_file(\"/path/to/file.txt\", \"search string\"):\n    print(\"String found!\")\n\n# Replace content in a file\nbash.replace_in_file(\"/path/to/file.txt\", \"old_pattern\", \"new_content\")\n\n# Change file permissions\nbash.chmod(\"/path/to/file.txt\", \"755\")\n\n# Change file ownership\nbash.chown(\"/path/to/file.txt\", \"user\", \"group\")\n```\n\n### System Operations\n\n```python\n# Detect the system's package manager\npackage_manager = bash.detect_package_manager()\nprint(f\"Using package manager: {package_manager}\")\n\n# Install packages\nbash.install([\"git\", \"curl\", \"wget\"])\n\n# Create a directory\nbash.mkdir(\"/path/to/directory\")\n\n# Change directory\nbash.cd(\"/path/to/directory\")\n\n# Remove a file or directory\nbash.rm(\"/path/to/file.txt\")\nbash.rm(\"/path/to/directory\", recursive=True)\n\n# Ensure sudo is available\nif bash.ensure_sudo():\n    print(\"Sudo is available\")\n```\n\n### Archive Operations\n\n```python\n# Create an archive\nbash.archive(\"/source/directory\", \"/path/to/archive.tar.gz\", format=\"tar.gz\")\n\n# Extract an archive\nbash.extract(\"/path/to/archive.tar.gz\", \"/destination/directory\")\n\n# Compress a file with gzip\nbash.gzip(\"/path/to/file.txt\", keep_original=True)\n\n# Decompress a gzipped file\nbash.gunzip(\"/path/to/file.txt.gz\", keep_original=False)\n\n# Download a file\nbash.download(\"https://example.com/file.txt\", \"/path/to/save/file.txt\")\n```\n\n### Colorful Output\n\n```python\n# Display messages in different colors\nbash.error(\"This is an error message\")  # Red\nbash.warning(\"This is a warning message\")  # Yellow\nbash.success(\"This is a success message\")  # Green\nbash.info(\"This is an info message\")  # Blue\n\n# Use the echo method with colors\nbash.echo(\"This is a colored message\", color=\"cyan\")\n```\n\n## Command Execution in a Directory\n\n```python\n# Execute a command in a specific directory\noutput = bash.execute_in_directory(\"ls -la\", \"/path/to/directory\")\n```\n\n## Error Handling\n\nMost methods return `True` if successful and `False` if they fail, making it easy to check for errors:\n\n```python\nif not bash.mkdir(\"/path/to/directory\"):\n    print(\"Failed to create directory\")\n```\n## Build for PyPI\n\nChange version in `setup.py` and run:\n\n```bash\nrm -rf dist/*\npython3 setup.py sdist bdist_wheel\npython3 -m twine upload dist/*\n```\n\nAdd credentials to `~/.pypirc`:\n\n```\n[pypi]\nusername = __token__\npassword = pypi-AgEIcH***\n```\n\nOr use environment variables:\n\n```bash\nexport PYPI_USERNAME=__token__\nexport PYPI_PASSWORD=pypi-AgEIcH***\n```\n\n## Installation\n\n```bash\nsudo apt install python3 python3-pip\npip3 install basher2\n```\n\n## Testing\n\n```bash\n# Pytest (147 tests)\npython3 -m pytest tests/ -v\n\n# Legacy tests\npython3 tests.py\n```\n\n## Docker (OroCommerce \u0026 Magento install scripts)\n\n**Prerequisites:** Docker and Docker Compose.\n\n### Quick start\n\n```bash\n# Build the image\ndocker compose build\n\n# Run Magento full install (non-interactive)\ndocker compose run --rm magento-install --no-interaction\n\n# Run OroCommerce full install (non-interactive)\ndocker compose run --rm oro-install --no-interaction\n```\n\n### Magento install (`install-magento.py`)\n\nInstalls: PHP 8.2, Composer, Nginx, MySQL, Redis, Elasticsearch. Magento is installed at `/var/www/html/magento`.\n\n```bash\n# Interactive menu (choose steps with arrow keys)\ndocker compose run --rm magento-install\n\n# Full install (runs all steps automatically)\ndocker compose run --rm magento-install --no-interaction\n```\n\n### Test Magento install inside container\n\nGet a shell inside the container and run the install manually:\n\n```bash\n# Start interactive shell (overrides default entrypoint)\ndocker compose run --rm --entrypoint bash magento-install\n\n# Inside the container (/app is the project root):\npython3 install-magento.py                    # interactive menu\npython3 install-magento.py --no-interaction   # full install\n```\n\nFrom the interactive menu you can run individual steps (1–8): Packages, PHP, Nginx, MySQL, Redis, Elasticsearch, Magento setup, or Full installation.\n\n### OroCommerce install (`install-oro.py`)\n\nInstalls: PHP 8.3, Composer, Node.js, Nginx, Supervisor, MySQL/PostgreSQL, Redis, Elasticsearch.\n\n```bash\ndocker compose run --rm oro-install                    # interactive menu\ndocker compose run --rm oro-install --no-interaction   # full install\n```\n\n### Script options\n\n| Option | Description |\n|--------|-------------|\n| `--no-interaction` | Full install without prompts |\n| `-v`, `--verbose` | Increase verbosity |\n| `-n`, `--no-inp` | No input mode |\n\n### Notes\n\n- The project is mounted at `/app`, so code changes are reflected immediately without rebuilding.\n- Build with verbose output: `docker compose build --progress=plain`\n\n## License\n\nMIT\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgenaker%2Fbasher","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgenaker%2Fbasher","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgenaker%2Fbasher/lists"}