{"id":1397,"library":"bashlex","title":"Bashlex: Bash Parser","description":"Bashlex is a Python library providing a parser for bash commands. It can take a bash command string and convert it into an Abstract Syntax Tree (AST), allowing for programmatic inspection and manipulation of shell commands. The current version is 0.18, with releases occurring roughly annually or bi-annually.","status":"active","version":"0.18","language":"en","source_language":"en","source_url":"https://github.com/idank/bashlex","tags":["bash","parser","shell","ast","cli","command-line"],"install":[{"cmd":"pip install bashlex","lang":"bash","label":"Install stable version"}],"dependencies":[],"imports":[{"symbol":"parse","correct":"from bashlex import parse"},{"symbol":"tokenize","correct":"from bashlex import tokenize"}],"quickstart":{"code":"import bashlex\n\ncommand_string = \"echo 'Hello World' && ls -l $HOME/#my-list.txt\"\n\ntry:\n    # Parse the command string into an Abstract Syntax Tree (AST)\n    tree = bashlex.parse(command_string)\n\n    print(f\"Parsed command: {command_string}\")\n    print(\"--- AST Structure ---\")\n    for i, part in enumerate(tree):\n        print(f\"[{i}] Kind: {part.kind}, Value: {part.word if hasattr(part, 'word') else str(part)}\")\n        if hasattr(part, 'parts'):\n            for p_sub in part.parts:\n                print(f\"  - Sub-part Kind: {p_sub.kind}, Word: {p_sub.word if hasattr(p_sub, 'word') else p_sub.value}\")\n\n    # Example: Tokenize the command to see all tokens, including comments and operators\n    print(\"\\n--- Tokens (including comments/operators) ---\")\n    tokens = bashlex.tokenize(command_string)\n    for token in tokens:\n        print(f\"Token: '{token.word}', Pos: ({token.pos[0]},{token.pos[1]}), Kind: {token.kind}\")\n\nexcept bashlex.errors.BashlexError as e:\n    print(f\"Error parsing command: {e}\")\n","lang":"python","description":"This quickstart demonstrates parsing a bash command string using `bashlex.parse()` to obtain an AST, and `bashlex.tokenize()` to get all individual tokens including operators and comments. It shows how to inspect the structure and access parts of the parsed command."},"warnings":[{"fix":"Do not expect `bashlex` to resolve environment variables, execute subcommands, or expand file paths. It provides the parsed structure, which you can then process with other tools or logic.","message":"Bashlex is strictly a *syntax parser* for bash commands and does not act as a shell emulator. It will not perform variable expansion (e.g., `$VAR`, `~`), command substitution (e.g., `$(cmd)`), globbing (`*`), or interpret complex shell logic. Users are responsible for implementing these behaviors if needed after parsing.","severity":"gotcha","affected_versions":"All versions"},{"fix":"For comment awareness, iterate through `bashlex.tokenize()` output. For command structure without comments, `bashlex.parse()` is appropriate.","message":"Comments (`# ...`) are parsed as distinct tokens during `bashlex.tokenize()` but are generally *not* included as part of the AST `parts` of command nodes returned by `bashlex.parse()`. If your application requires analyzing or extracting comments, you must use the `bashlex.tokenize()` function directly.","severity":"gotcha","affected_versions":"All versions"},{"fix":"In Python 3, always pass unicode strings to `bashlex` functions. If dealing with byte strings from external sources, decode them explicitly before passing to `bashlex`.","message":"The library maintains compatibility with both Python 2.7 and Python 3.5+. While this broad support exists, be cautious about `str`/`bytes` differences between Python 2 and 3 when processing input, especially in mixed environments or when migrating legacy code. Ensure your input strings are consistent (e.g., unicode in Python 3).","severity":"gotcha","affected_versions":"All versions up to 0.18"}],"env_vars":null,"last_verified":"2026-04-09T00:00:00.000Z","next_check":"2026-07-08T00:00:00.000Z"}