Comments (4)
Hey, that's awesome, glad you found a use for it. :)
I don't think anyone has, but it sounds pretty doable. As far as getting it to look like a real shell like bash, that'd be a different story I think. It does beg the question why you can't just pass it through the shell.
from bashlex.
I don't think anyone has, but it sounds pretty doable.
Agreed! I'm taking a crack at it today :)
It does beg the question why you can't just pass it through the shell.
Long story short, Windows compatibility.
I'll let you know if I get anywhere.
from bashlex.
Here's what I did, for reference.
It evaluates values like "variable: $USERNAME, computed $(pwd)"
, as used in environment variable declarations VAR=somevalue
. Pretty simple. The only thing that was tricky (and might not be 100% correct) is the 'bash-like quotes/whitespace treatment' at the end of evaluate_word_node, but it's been pretty accurate in my testing.
bashlex_eval.py
import subprocess, shlex
from collections import namedtuple
import bashlex
NodeExecutionContext = namedtuple('NodeExecutionContext', ['environment', 'input'])
def evaluate(value, environment):
if not value:
# empty string evaluates to empty string
# (but trips up bashlex)
return ''
command_node = bashlex.parsesingle(value)
if len(command_node.parts) != 1:
raise ValueError('"%s" has too many parts' % value)
value_word_node = command_node.parts[0]
return evaluate_node(
value_word_node,
context=NodeExecutionContext(environment=environment, input=value)
)
def evaluate_node(node, context):
if node.kind == 'word':
return evaluate_word_node(node, context=context)
elif node.kind == 'commandsubstitution':
return evaluate_command_node(node.command, context=context)
elif node.kind == 'parameter':
return evaluate_parameter_node(node, context=context)
else:
raise ValueError('Unsupported bash construct: "%s"' % node.word)
def evaluate_word_node(node, context):
word_start = node.pos[0]
word_end = node.pos[1]
word_string = context.input[word_start:word_end]
letters = list(word_string)
for part in node.parts:
part_start = part.pos[0] - word_start
part_end = part.pos[1] - word_start
# Set all the characters in the part to None
for i in range(part_start, part_end):
letters[i] = None
letters[part_start] = evaluate_node(part, context=context)
# remove the None letters and concat
value = ''.join(l for l in letters if l is not None)
# apply bash-like quotes/whitespace treatment
return ' '.join(word.strip() for word in shlex.split(value))
def evaluate_command_node(node, context):
words = [evaluate_node(part, context=context) for part in node.parts]
command = ' '.join(words)
return subprocess.check_output(shlex.split(command), env=context.environment)
def evaluate_parameter_node(node, context):
return context.environment.get(node.value, '')
from bashlex.
Nice, glad you got something working. You could also use a nodevisitor to traverse the parsed statement.
from bashlex.
Related Issues (20)
- bashlex is creating python files at import time HOT 4
- Parsing fails for *some* list nodes inside command substitution nodes.
- space at the end of line - parse error HOT 3
- importing the ABCs from 'collections' instead of from 'collections.abc' error HOT 3
- [request] Ship wheels too HOT 4
- ANSI-C quoted strings $'' aren't supported HOT 3
- "a\\ \n" is not treated the same as "a\\\n"
- Variable names cannot have numbers in them
- Airthmetic Command Implementation HOT 3
- [request] Add support for local, global, and export HOT 3
- If statements only have support for conditional commands (COND_CMD)
- Multiple new lines at end of file HOT 3
- backslash newline fails
- New release - When ? HOT 2
- Issues with parsing && and ||
- Parsing scripts with arrays HOT 2
- add unimplemented nodes to AST instead of raising exceptions HOT 3
- add support for using unimplemented nodes for array assignment HOT 3
- case statement parsing?
- How to check if a line is a complete bash command or not? HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from bashlex.