### Install bashlex Source: https://github.com/idank/bashlex/blob/master/README.md Install the package using pip. ```bash $ pip install bashlex ``` -------------------------------- ### Dump AST Node Structure for Debugging Source: https://context7.com/idank/bashlex/llms.txt Uses the .dump() method to get a formatted string representation of an AST node and its children, useful for debugging. ```python import bashlex # Dump a complex command structure parts = bashlex.parse('for i in a b c; do echo $i; done') for tree in parts: print(tree.dump()) ``` ```python import bashlex # Dump an if statement parts = bashlex.parse('if [ -f file ]; then cat file; fi') print(parts[0].dump()) ``` -------------------------------- ### Set up release environment Source: https://github.com/idank/bashlex/blob/master/README.md Commands to prepare a virtual environment for releasing a new version. ```bash python3 -m venv venv source venv/bin/activate pip install -r requirements.txt ``` -------------------------------- ### Debug bashlex with GNU bash Source: https://github.com/idank/bashlex/blob/master/README.md Commands to set up a debugging environment using the GNU bash source code. ```bash $ git clone git://git.sv.gnu.org/bash.git $ cd bash $ git checkout df2c55de9c87c2ee8904280d26e80f5c48dd6434 # commit used in translating the code $ ./configure $ make CFLAGS=-g CFLAGS_FOR_BUILD=-g # debug info and don't optimize $ gdb --args ./bash -c 'echo foo' ``` -------------------------------- ### Custom AST Visitor for Command Substitutions Source: https://context7.com/idank/bashlex/llms.txt Implements a custom AST visitor to find all command substitutions within a parsed bash script. Returns False from visit methods to prevent recursion into child nodes. ```python from bashlex import ast, parser # Custom visitor to find all command substitutions class CommandSubstitutionFinder(ast.nodevisitor): def __init__(self): self.substitutions = [] def visitcommandsubstitution(self, node, command): # Store the position of this substitution self.substitutions.append(node.pos) # Return False to skip recursing into nested substitutions # Return True or None to continue recursion return False # Parse and visit parts = parser.parse('echo $(cat $(ls))') finder = CommandSubstitutionFinder() for tree in parts: finder.visit(tree) print(finder.substitutions) # [(5, 17)] ``` -------------------------------- ### Custom AST Visitor to Collect All Words Source: https://context7.com/idank/bashlex/llms.txt Implements a custom AST visitor to collect all 'word' nodes from a parsed bash script. ```python from bashlex import ast, parser # Visitor that collects all words class WordCollector(ast.nodevisitor): def __init__(self): self.words = [] def visitword(self, node, word): self.words.append(word) parts = parser.parse('git commit -m "message"') collector = WordCollector() for tree in parts: collector.visit(tree) print(collector.words) # ['git', 'commit', '-m', '"message"'] ``` -------------------------------- ### Handle Parsing Errors in Bashlex Source: https://context7.com/idank/bashlex/llms.txt Demonstrates how to catch and report ParsingErrors for incomplete or invalid bash commands using bashlex.parse(). ```python try: bashlex.parse('if true; then') except ParsingError as e: print(f"Parsing failed: {e}") ``` ```python try: bashlex.parse('echo ||') except ParsingError as e: print(f"Error at position {e.position}: {e.message}") ``` -------------------------------- ### Split Bash Commands with bashlex.split Source: https://context7.com/idank/bashlex/llms.txt Tokenizes bash command strings into words, correctly handling complex constructs like process substitutions, command substitutions, and quotes. It's a more robust alternative to shlex.split. ```python import bashlex import shlex # bashlex.split handles complex constructs correctly result = list(bashlex.split('cat <(echo "a $(echo b)") | tee')) print(result) # Output: ['cat', '<(echo "a $(echo b)")', '|', 'tee'] # Compare with shlex.split which fails on process substitution shlex_result = shlex.split('cat <(echo "a $(echo b)") | tee') print(shlex_result) # Output: ['cat', '<(echo', 'a $(echo b))', '|', 'tee'] # Incorrect! # Additional examples print(list(bashlex.split('a b"c"\'d\''))) # Output: ['a', 'bcd'] print(list(bashlex.split('a "b $(c)" $(d) \'$(e)\''))) # Output: ['a', 'b $(c)', '$(d)', '$(e)'] print(list(bashlex.split('a b\n'))) # Output: ['a', 'b', '\n'] ``` -------------------------------- ### bashlex.parsesingle Source: https://context7.com/idank/bashlex/llms.txt Parses only the first top-level command from an input string. ```APIDOC ## bashlex.parsesingle ### Description Parses a single top-level command from the input string, leaving any remaining input unparsed. Useful for incremental processing. ### Parameters - **input** (string) - Required - The bash command string to parse. ### Request Example ```python import bashlex tree = bashlex.parsesingle('a\nb') ``` ### Response - **node** (object) - The AST node representing the first command. ``` -------------------------------- ### bashlex.ast.nodevisitor Source: https://context7.com/idank/bashlex/llms.txt A base class for traversing AST nodes. Subclass this to implement custom logic by overriding visit methods. ```APIDOC ## bashlex.ast.nodevisitor ### Description Base class for traversing AST nodes. Implement custom logic by overriding visit methods (e.g., visitcommandsubstitution, visitword). Return False to stop recursion into child nodes. ### Methods - **visit(node)** - Starts the traversal of the node. - **visit[node_type](node, ...)** - Override these methods to handle specific node types. ``` -------------------------------- ### Bashlex AST Node Types Source: https://context7.com/idank/bashlex/llms.txt Illustrates the various kinds of nodes available in the bashlex Abstract Syntax Tree (AST), such as commands, pipelines, lists, and words. Each node has a 'kind' and 'pos' attribute. ```python from bashlex import ast # Node kinds include: # - command: simple commands # - pipeline: series of piped commands # - list: series of pipelines (using &&, ||, ;, &) # - compound: control structures (if, for, while, case, etc.) # - word: command arguments and words # - assignment: variable assignments (VAR=value) # - redirect: I/O redirections (>, <, >>, etc.) # - pipe: pipe operator | # - operator: operators (&&, ||, ;, &) ``` -------------------------------- ### bashlex.parse Source: https://context7.com/idank/bashlex/llms.txt Parses a full bash command string into a list of AST nodes. ```APIDOC ## bashlex.parse ### Description Parses a bash command string and returns a list of AST nodes representing the parsed commands. This is the primary entry point for parsing multi-line bash scripts or commands separated by newlines. ### Parameters - **parts** (string) - Required - The bash command string to parse. - **strictmode** (boolean) - Optional - If True, skips heredoc at end of input. - **expansionlimit** (int) - Optional - Limits recursion depth for command substitutions. - **convertpos** (boolean) - Optional - If True, converts position tuples to 's' attribute containing the source string. - **proceedonerror** (boolean) - Optional - If True, returns AST nodes for unimplemented features instead of raising exceptions. ### Request Example ```python import bashlex parts = bashlex.parse('true && cat <(echo $(echo foo))') ``` ### Response - **list** (list) - A list of AST nodes representing the parsed commands. ``` -------------------------------- ### Split bash commands Source: https://github.com/idank/bashlex/blob/master/README.md Use bashlex.split to tokenize complex bash constructs, which handles substitutions better than the standard shlex library. ```python >>> list(bashlex.split('cat <(echo "a $(echo b)") | tee')) ['cat', '<(echo "a $(echo b)")', '|', 'tee'] ``` ```python >>> shlex.split('cat <(echo "a $(echo b)") | tee') ['cat', '<(echo', 'a $(echo b))', '|', 'tee'] ``` -------------------------------- ### Highlight Bash Syntax Using Position Information Source: https://context7.com/idank/bashlex/llms.txt A utility function to highlight specific positions within a bash source string using ANSI color codes. It requires the source string and a list of start/end positions. ```python source = 'git commit -m "fix bug"' parts = bashlex.parse(source) def highlight(text, positions, color_code='\033[91m'): """Highlight specific positions in text""" reset = '\033[0m' result = list(text) for start, end in sorted(positions, reverse=True): result.insert(end, reset) result.insert(start, color_code) return ''.join(result) ``` -------------------------------- ### bashlex.ast.node.dump Source: https://context7.com/idank/bashlex/llms.txt Returns a formatted string representation of the AST node and its children. ```APIDOC ## bashlex.ast.node.dump() ### Description Returns a string representation of the AST node structure. Useful for debugging and understanding the hierarchy of parsed commands. ``` -------------------------------- ### Parse bash commands Source: https://github.com/idank/bashlex/blob/master/README.md Use bashlex.parse to generate an AST from a bash command string. ```python >>> import bashlex >>> parts = bashlex.parse('true && cat <(echo $(echo foo))') >>> for ast in parts: ... print ast.dump() ``` -------------------------------- ### Handle Bashlex Parsing Errors Source: https://context7.com/idank/bashlex/llms.txt Demonstrates how to catch and handle `bashlex.errors.ParsingError` exceptions that are raised when invalid bash syntax is encountered during parsing. The exception object provides details about the error. ```python import bashlex from bashlex.errors import ParsingError # Handle parsing errors try: bashlex.parse('echo "unclosed string') except ParsingError as e: print(f"Error: {e.message}") print(f"Position: {e.position}") print(f"Source: {e.s}") # Output: # Error: unexpected EOF while looking for matching '"' # Position: 21 # Source: echo "unclosed string ``` -------------------------------- ### bashlex.split Source: https://context7.com/idank/bashlex/llms.txt Tokenizes a bash command string into individual words while preserving complex bash constructs. ```APIDOC ## bashlex.split ### Description A utility function that tokenizes a bash command string into individual words, correctly handling process substitutions, command substitutions, and quoted strings. ### Parameters - **command** (string) - Required - The bash command string to tokenize. ### Request Example ```python import bashlex result = list(bashlex.split('cat <(echo "a $(echo b)") | tee')) ``` ### Response - **list** (list) - A list of strings representing the tokenized words. ``` -------------------------------- ### bashlex.parse Source: https://context7.com/idank/bashlex/llms.txt Parses a bash script string into a list of AST nodes. ```APIDOC ## bashlex.parse(script) ### Description Parses the provided bash script string and returns a list of AST nodes representing the commands. ### Parameters - **script** (string) - Required - The bash script to parse. ### Response - **list** (list of nodes) - A list of AST nodes representing the parsed commands. ``` -------------------------------- ### Parse Single Bash Command with bashlex.parsesingle Source: https://context7.com/idank/bashlex/llms.txt Parses only the first top-level command from an input string, leaving the rest unparsed. Useful for incremental processing or extracting the initial command. ```python import bashlex # Only parse the first command, leaving 'b' unparsed tree = bashlex.parsesingle('a\nb') # Returns node for 'a' only print(tree.dump()) # Output: # CommandNode(pos=(0, 1), parts=[ # WordNode(pos=(0, 1), word='a'), # ]) # Useful for interactive parsing or streaming input script = '''echo first echo second echo third''' # Parse just the first statement first_cmd = bashlex.parsesingle(script) print(first_cmd.parts[0].word) # 'echo' print(first_cmd.parts[1].word) # 'first' ``` -------------------------------- ### bashlex.errors.ParsingError Source: https://context7.com/idank/bashlex/llms.txt Exception raised when the parser encounters invalid bash syntax. ```APIDOC ## bashlex.errors.ParsingError ### Description Exception raised during parsing failures. ### Attributes - **message** (string) - The error description. - **position** (int) - The character index where the error occurred. - **s** (string) - The original source string being parsed. ``` -------------------------------- ### Replace Command Substitutions in Bash Script Source: https://context7.com/idank/bashlex/llms.txt Traverses the AST to find and replace command substitutions (e.g., $() and ``) with a specified replacement string. Positions are processed in reverse to avoid index issues. ```python from bashlex import parser, ast class CommandSubstitutionRemover(ast.nodevisitor): """Finds all command substitutions and records their positions""" def __init__(self): self.positions = [] def visitcommandsubstitution(self, node, command): self.positions.append(node.pos) return False # Don't recurse into nested substitutions def replace_substitutions(script, replacement='XXX'): """Replace all $() and `` with a replacement string""" trees = parser.parse(script) positions = [] for tree in trees: visitor = CommandSubstitutionRemover() visitor.visit(tree) positions.extend(visitor.positions) # Sort positions in reverse order to replace from end to start positions.sort(reverse=True) result = list(script) for start, end in positions: result[start:end] = replacement return ''.join(result) # Example usage script = 'foo $(bar) && echo "$(baz $(qux))"' result = replace_substitutions(script, 'REPLACED') print(result) # Output: foo REPLACED && echo "REPLACED" # With different replacement result = replace_substitutions('echo $(date)', '[REDACTED]') print(result) # Output: echo [REDACTED] ``` -------------------------------- ### Parse Bash Commands with bashlex.parse Source: https://context7.com/idank/bashlex/llms.txt Parses multi-line bash scripts or commands separated by newlines into a list of AST nodes. Supports options for strict parsing, recursion depth, and position conversion. ```python import bashlex # Parse a simple command with process substitution and command substitution parts = bashlex.parse('true && cat <(echo $(echo foo))') # Iterate through parsed AST nodes for ast in parts: print(ast.dump()) # Output: # ListNode(pos=(0, 31), parts=[ # CommandNode(pos=(0, 4), parts=[ # WordNode(pos=(0, 4), word='true'), # ]), # OperatorNode(op='&&', pos=(5, 7)), # CommandNode(pos=(8, 31), parts=[ # WordNode(pos=(8, 11), word='cat'), # WordNode(pos=(12, 31), word='<(echo $(echo foo))', parts=[ # ProcesssubstitutionNode(command= # CommandNode(pos=(14, 30), parts=[ # WordNode(pos=(14, 18), word='echo'), # WordNode(pos=(19, 30), word='$(echo foo)', parts=[ # CommandsubstitutionNode(command= # CommandNode(pos=(21, 29), parts=[ # WordNode(pos=(21, 25), word='echo'), # WordNode(pos=(26, 29), word='foo'), # ]), pos=(19, 30)), # ]), # ]), pos=(12, 31)), # ]), # ]), # ]) # Parse with options # strictmode=False: skip heredoc at end of input # expansionlimit=N: limit recursion depth for command substitutions # convertpos=True: convert position tuples to 's' attribute containing the source string # proceedonerror=True: return AST nodes for unimplemented features instead of raising exceptions parts = bashlex.parse('echo hello', strictmode=True, expansionlimit=None, convertpos=False) ``` -------------------------------- ### Parse Bash Commands with Source Substrings Source: https://context7.com/idank/bashlex/llms.txt Parses a bash command with convertpos=True to include the source substring as an 's' attribute on each node. ```python parts = bashlex.parse('echo hello', convertpos=True) cmd = parts[0] print(cmd.s) # 'echo hello' for part in cmd.parts: print(f"Source: '{part.s}'") ``` -------------------------------- ### Parse Bash Command and Access AST Nodes Source: https://context7.com/idank/bashlex/llms.txt Parses a bash command string and accesses attributes of the resulting AST nodes, such as kind and position. ```python import bashlex parts = bashlex.parse('echo $HOME > output.txt') cmd = parts[0] print(cmd.kind) # 'command' print(cmd.pos) # (0, 23) for part in cmd.parts: print(f" {part.kind}: {part.word if hasattr(part, 'word') else part}") ``` -------------------------------- ### Parse Bash Commands with Position Information Source: https://context7.com/idank/bashlex/llms.txt Parses a bash command and iterates through its parts, printing the word and its start/end positions in the source string. ```python import bashlex # Standard parsing with position tuples parts = bashlex.parse('echo hello world') cmd = parts[0] for part in cmd.parts: start, end = part.pos print(f"'{part.word}' at positions {start}-{end}") ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.