[kupfer] commands: Use subshells for all execution



commit 7882252fa7d242fb15ac476b623c687e3111d26b
Author: Ulrik Sverdrup <ulrik sverdrup gmail com>
Date:   Wed Mar 16 23:01:10 2011 +0100

    commands: Use subshells for all execution
    
    The shell sh will parse the commandline for us and it allows the user
    to use real shell pipelines. It also rids of all the pesky parsing and
    escape issues.
    
    Applies to Run (Get Output), Filter through Command, Pass to Command,
    Write to Command..
    
    For FileLeaves we still just run them straighforwardly.

 kupfer/plugin/commands.py |   46 ++++++++++++--------------------------------
 1 files changed, 13 insertions(+), 33 deletions(-)
---
diff --git a/kupfer/plugin/commands.py b/kupfer/plugin/commands.py
index b9d824e..46a01a9 100644
--- a/kupfer/plugin/commands.py
+++ b/kupfer/plugin/commands.py
@@ -11,7 +11,6 @@ __version__ = ""
 __author__ = "Ulrik Sverdrup <ulrik sverdrup gmail com>"
 
 import os
-import shlex
 
 import gobject
 
@@ -23,31 +22,6 @@ from kupfer import commandexec
 from kupfer import kupferstring
 from kupfer import pretty
 
-def unicode_shlex_split(ustr, **kwargs):
-	"""shlex.split is depressingly broken on unicode input"""
-	s_str = ustr.encode("UTF-8")
-	return [kupferstring.tounicode(t) for t in shlex.split(s_str, **kwargs)]
-
-def rm_quotes(us):
-	"""Remove "quotes" -> quotes if wrapped in " or ' quotes"""
-	if len(us) > 1 and us[0] in ("'", '"') and us[0] == us[-1]:
-		return us[1:-1]
-	return us
-
-def custom_shlex_split(ustr):
-	# Use posix=False so that we don't swallow backslashes "\"
-	# After that we have to remove quotes ourselves
-	return map(rm_quotes, unicode_shlex_split(ustr, posix=False))
-
-def get_commandline_argv(commandline):
-	""" Use shlex to allow simple quoting in the commandline """
-	try:
-		argv = custom_shlex_split(commandline)
-	except ValueError:
-		# Exception raised on unpaired quotation marks
-		argv = commandline.split(None, 1)
-	return argv
-
 def finish_command(token, acommand, stdout, stderr, post_result=True):
 	"""Show async error if @acommand returns error output & error status.
 	Else post async result if @post_result.
@@ -71,7 +45,10 @@ class GetOutput (Action):
 		Action.__init__(self, _("Run (Get Output)"))
 
 	def activate(self, leaf):
-		argv = get_commandline_argv(leaf.object)
+		if isinstance(leaf, Command):
+			argv = ['sh', '-c', leaf.object, '--']
+		else:
+			argv = [leaf.object]
 		ctx = commandexec.DefaultActionExecutionContext()
 		token = ctx.get_async_token()
 		pretty.print_debug(__name__, "Spawning with timeout 15 seconds")
@@ -82,7 +59,7 @@ class GetOutput (Action):
 		finish_command(acommand.token, acommand, stdout, stderr)
 
 	def get_description(self):
-		return _("Run program and return its output")
+		return _("Run program and return its output") + u" \N{GEAR}"
 
 class PassToCommand (Action):
 	def __init__(self):
@@ -95,7 +72,7 @@ class PassToCommand (Action):
 
 	def _run_command(self, objs, iobj):
 		if isinstance(iobj, Command):
-			argv = get_commandline_argv(iobj.object)
+			argv = ['sh', '-c', iobj.object + ' "$@"', '--']
 		else:
 			argv = [iobj.object]
 		argv.extend([o.object for o in objs])
@@ -129,7 +106,8 @@ class PassToCommand (Action):
 		finish_command(acommand.token, acommand, stdout, stderr, False)
 
 	def get_description(self):
-		return _("Run program with object as an additional parameter")
+		return _("Run program with object as an additional parameter") + \
+		        u" \N{GEAR}"
 
 
 class WriteToCommand (Action):
@@ -140,7 +118,7 @@ class WriteToCommand (Action):
 
 	def activate(self, leaf, iobj):
 		if isinstance(iobj, Command):
-			argv = get_commandline_argv(iobj.object)
+			argv = ['sh', '-c', iobj.object]
 		else:
 			argv = [iobj.object]
 		ctx = commandexec.DefaultActionExecutionContext()
@@ -169,7 +147,8 @@ class WriteToCommand (Action):
 		finish_command(acommand.token, acommand, stdout, stderr, False)
 
 	def get_description(self):
-		return _("Run program and supply text on the standard input")
+		return _("Run program and supply text on the standard input") + \
+		        u" \N{GEAR}"
 
 class FilterThroughCommand (WriteToCommand):
 	def __init__(self):
@@ -182,7 +161,8 @@ class FilterThroughCommand (WriteToCommand):
 		finish_command(acommand.token, acommand, stdout, stderr)
 
 	def get_description(self):
-		return _("Run program and supply text on the standard input")
+		return _("Run program and supply text on the standard input") + \
+		        u" \N{GEAR}"
 
 class Command (TextLeaf):
 	def __init__(self, exepath, name):



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]