{"id":47612203,"url":"https://gitlab.com/licorna/shellwrap","last_synced_at":"2026-04-01T20:34:16.697Z","repository":{"id":57466755,"uuid":"7807461","full_name":"licorna/shellwrap","owner":"licorna","description":"","archived":false,"fork":false,"pushed_at":null,"size":null,"stargazers_count":1,"open_issues_count":7,"forks_count":0,"subscribers_count":null,"default_branch":"master","last_synced_at":"2025-11-27T20:13:11.600Z","etag":null,"topics":["bash","scripting","shell"],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":null,"metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-08-08T00:56:30.347Z","updated_at":"2018-08-20T18:18:43.268Z","dependencies_parsed_at":"2022-09-19T08:41:41.076Z","dependency_job_id":null,"html_url":"https://gitlab.com/licorna/shellwrap","commit_stats":null,"previous_names":[],"tags_count":0,"template":null,"template_full_name":null,"purl":"pkg:gitlab/licorna/shellwrap","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/gitlab.com/repositories/licorna%2Fshellwrap","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/gitlab.com/repositories/licorna%2Fshellwrap/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/gitlab.com/repositories/licorna%2Fshellwrap/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/gitlab.com/repositories/licorna%2Fshellwrap/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/gitlab.com/owners/licorna","download_url":"https://gitlab.com/licorna/shellwrap/-/archive/master/shellwrap-master.zip","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/gitlab.com/repositories/licorna%2Fshellwrap/sbom","scorecard":null,"host":{"name":"gitlab.com","url":"https://gitlab.com","kind":"gitlab","repositories_count":4521539,"owners_count":7348,"icon_url":"https://github.com/gitlab.png","version":null,"created_at":"2022-05-30T11:31:42.605Z","updated_at":"2026-01-12T22:45:04.389Z","status":"online","status_checked_at":"2026-04-01T02:00:08.192Z","response_time":245,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.382Z","robots_txt_url":"https://gitlab.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/gitlab.com","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/gitlab.com/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/gitlab.com/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/gitlab.com/owners"}},"keywords":["bash","scripting","shell"],"created_at":"2026-04-01T20:34:15.846Z","updated_at":"2026-04-01T20:34:16.693Z","avatar_url":null,"language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# ShellWrap\n\nThis small module allows you to write `shell` commands inside your\nPython program. This module is not a replacement for `subprocess` or\nany of the Python modules that are a high level abstractions on top of\nprogram and command execution or shell interaction. On the contrary\nShellWrap executes a shell interpreter that will live as long as your\nPython script is running. A simple function decorator will allow\nPython function to have a shell script body. These functions will be\naugmented and passed to the shell interpreter. Let's start with some\nexamples:\n\n## Example: Check if a site is UP\n\nThis example will regularily check for the given site to respond with a 200, Ok.\nThis is handy when you are waiting for a site to become responsive or waiting\nfor it to boot up.\n\n``` python\nimport time\nfrom shellwrap import ShellWrap\nshell = ShellWrap('bash').get_shell()\n\n@shell()\ndef is_the_site_up(url):\n    'curl -sL -m 2 -w \"%{http_code}\" \"${url}\" -o /dev/null | grep -q 200'\n\nwhile is_the_site_up('https://google.com').fails():\n    time.sleep(4)\n```\n\nYou just have to annotate a function with the `@shell` decorator and it will\nbe parsed and each line (a loose string) will be fed into a running `bash`\ninterpreter.\n\n## Example: Passing arguments to functions\n\nYou can define a function with arguments, like `is_the_site_up` above and these\narguments will be converted into variables for the execution of your function,\ninside the `bash` environment.\n\n```python\n@shell()\ndef passing_arguments_to_funcs(arg0, arg1, someother):\n    'echo \"got $arg0 and $arg1\"'\n    'echo \"and also $someother\"'\n\nresult = passing_arguments_to_funcs('hello', 10, 'love you bash')\n\nassert(result.exitcode == 0)\n```\n\nThis will result in the following being displayed:\n\n```\ngot hello and 10\nand also I love you bash\n```\n\n## Example: Timeouts\n\nYou might have a process that you only want to execute for a few seconds, for it to return.\nIf the process get stuck, you want to kill it and continue with your life. This is possible\nwith `ShellWrap` by using the `timeout` parameter in your decorator.\n\n``` python\n@shell(timeout=3)\ndef will_timeout_in_3_secs(mymessage):\n    'sleep 1'\n    'echo \"${mymessage}\"'\n    'sleep 1'\n\nresult = will_timeout_in_3_secs('Only patience will reveal the truth.')\nif result.success():\n    print('Your patience will be rewarded')\n```\n\nIn the last example, we will give the decorated function 3 seconds to run, and we know it will\ntake around 2 seconds to complete. The first run will succeed, but if you change the `timeout`\nparameter to 1, the function will fail to complete in time, and it will be killed. The result of\na killed function is `fails()`.\n\n## Results\n\nThe return value of calling a function annotated with `@shell` is a `Result`\ntype that has a few convenience functions:\n\n* `Result().fails()` returns True if the command failed (its exitcode is != 0)\n* `Result().success()` returns True if the command succeeded (equivalent to `not .fails()`)\n* `Result().exitcode` contains the exit code of the last command executed in your function\n* `Result().stdout` contains all the output of the execution of your function\n\n# Contributing to the project\n\nPlease see our [Contribution](./CONTRIBUTE.md) page!\n\n# License\n\nThe project is distributed under the [MIT license](./LICENSE.txt).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/gitlab.com%2Flicorna%2Fshellwrap","html_url":"https://awesome.ecosyste.ms/projects/gitlab.com%2Flicorna%2Fshellwrap","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/gitlab.com%2Flicorna%2Fshellwrap/lists"}