aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bashast/bashast.g2
-rw-r--r--bashast/libbashWalker.g15
-rw-r--r--scripts/command_execution.bash4
3 files changed, 17 insertions, 4 deletions
diff --git a/bashast/bashast.g b/bashast/bashast.g
index 799b1cf..2226839 100644
--- a/bashast/bashast.g
+++ b/bashast/bashast.g
@@ -1197,7 +1197,7 @@ COMMAND_SUBSTITUTION_PAREN
| .
)+
));
-COMMAND_SUBSTITUTION_TICK : TICK (~(TICK))+ TICK;
+COMMAND_SUBSTITUTION_TICK : TICK .+ (~ESC) TICK;
ESC_LT : ESC'<';
ESC_GT : ESC'>';
diff --git a/bashast/libbashWalker.g b/bashast/libbashWalker.g
index 768129f..f50b32c 100644
--- a/bashast/libbashWalker.g
+++ b/bashast/libbashWalker.g
@@ -1132,13 +1132,22 @@ command_substitution returns[std::string libbash_value]
@declarations {
std::string subscript;
std::stringstream out;
+ current_streams streams(walker->get_output_stream(), walker->get_error_stream(), walker->get_input_stream());
}
:^(COMMAND_SUB { walker->set_output_stream(&out); } (libbash_string=any_string { subscript += libbash_string; })+) {
- if(subscript[0] == '`')
- bash_ast(std::stringstream(subscript.substr(1, subscript.size() - 2))).interpret_with(*walker);
+ if(subscript[0] == '`') {
+ std::string sub = subscript.substr(1, subscript.size() - 2);
+ // Escape \ and ' for nested command substitution
+ size_t pos = 0;
+ while((pos = sub.find("\\\\", pos)) != std::string::npos)
+ sub.erase(pos++, 1);
+ pos = 0;
+ while((pos = sub.find("\\`", pos)) != std::string::npos)
+ sub.erase(pos++, 1);
+ bash_ast(std::stringstream(sub)).interpret_with(*walker);
+ }
else
bash_ast(std::stringstream(subscript.substr(2, subscript.size() - 3))).interpret_with(*walker);
- walker->restore_output_stream();
$libbash_value = out.str();
walker->trim_trailing_eols($libbash_value);
};
diff --git a/scripts/command_execution.bash b/scripts/command_execution.bash
index df6275b..248de63 100644
--- a/scripts/command_execution.bash
+++ b/scripts/command_execution.bash
@@ -79,6 +79,10 @@ echo "$(echo 'hi')"
echo "`echo 'hi'`"
array=(`echo 1` `echo 2` 3)
echo ${array[@]}
+echo `echo 1`
+echo `echo 1 \`echo 2\` 3`
+echo `echo 1 \`echo 2 \\\`echo 3\\\` 4\` 5`
+echo $(echo 1 `echo 2 $(echo 3) 4` 5)
ech\
o Hello\
world