(patch for Bash) Python command substitution in Bash
William Park
opengeometry at yahoo.ca
Fri Feb 14 18:53:18 EST 2003
To Bash/Python programmers,
Here is my patch to "command substitution" syntax of Bash to interface
with Python automatically. Not quite "embedding", but close enough for
short one-liners.
If command string begins with '!', then the rest of string is sent to
Python as command-line argument with double quotes, ie.
python -c "string"
This shortcut is intended for one-liners like
b=$(!print (1+1j) + (2+3j) )
echo $(! print 'a' + '$b' )
echo $(! print [1,2] + ['q','w'] )
pi=$(!
import math
print math.pi
)
To improve readability, whitespaces after '!' are removed before sending
it to Python. Also, you have to turn off history substitution (set +H)
to use the '!' character interactively.
Since the commands are within double-quote, the usual shell expansions
are done, enabling you to use shell variables. For bigger jobs,
however, you should do something like
exec 9<<EOF (or "EOF")
...
...
EOF
python /dev/fd/9 ...
exec 9<&-
--
William Park, Open Geometry Consulting, <opengeometry at yahoo.ca>
Linux solution for data management and processing.
--- bash-2.05b/subst.c Mon Jun 24 07:59:45 2002
+++ bash/subst.c Fri Feb 14 18:34:09 2003
@@ -3842,8 +3842,46 @@
exit (EXECUTION_FAILURE);
else if (function_value)
exit (return_catch_value);
- else
- exit (parse_and_execute (string, "command substitution", SEVAL_NOHIST));
+ else if (string[0] == '!') {
+ /* If command string begins with '!', then the rest of string is sent
+ * to Python as command-line argument with double quotes, ie.
+ * python -c "string"
+ * This shortcut to Python is intended for one-liners like
+ * b=$(!print (1+1j) + (2+3j) )
+ * echo $(! print 'a' + '$b' )
+ * echo $(! print [1,2] + ['q','w'] )
+ * pi=$(!
+ * import math
+ * print math.pi
+ * )
+ * To improve readability, whitespaces after '!' are removed before
+ * sending it to Python. Also, you have to turn off history
+ * substitution (set +H) to use the '!' character interactively.
+ *
+ * Since the commands are within double-quote, the usual shell
+ * expansions are done, enabling you to use shell variables. For
+ * bigger jobs, however, you should do something like
+ * exec 9<<EOF (or "EOF")
+ * ...
+ * ...
+ * EOF
+ * python /dev/fd/9 ...
+ * exec 9<&-
+ *
+ * --William Park <opengeometry at yahoo.ca>
+ */
+ char *t, *newstring;
+
+ /* skip whitespaces after after '!' */
+ for (t = string + 1; (*t) && spctabnl (*t) && isifs (*t); t++)
+ ;
+ newstring = (char *)xmalloc (strlen (string) + strlen ("python -c \"\"") + 1);
+ sprintf (newstring, "python -c \"%s\"", t);
+
+ /* newstring is free'd by parse_and_execute() */
+ exit (parse_and_execute (newstring, "python command substitution", SEVAL_NOHIST));
+ } else /* original code */
+ exit (parse_and_execute (string, "command substitution", SEVAL_NOHIST));
}
else
{
@@ -4360,7 +4398,7 @@
#if defined (ARRAY_VARS)
case VT_ARRAYVAR:
a = (ARRAY *)value;
- len = array_num_elements (a) + 1;
+ len = array_num_elements (a); /* + 1; --William Park <opengeometry at yahoo.ca> */
break;
#endif
}
More information about the Python-list
mailing list