[kupfer: 45/67] commands: Use subshells for all execution



commit 71801d83636244ea7fc964b034dfac98f226407b
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.
    
    For FileLeaves we still just run them straighforwardly.

 kupfer/plugin/commands.py |   51 ++++++++++++++------------------------------
 1 files changed, 16 insertions(+), 35 deletions(-)
---
diff --git a/kupfer/plugin/commands.py b/kupfer/plugin/commands.py
index b9d824e..79df277 100644
--- a/kupfer/plugin/commands.py
+++ b/kupfer/plugin/commands.py
@@ -6,12 +6,12 @@ __kupfer_actions__ = (
 		"WriteToCommand",
 	)
 __kupfer_text_sources__ = ("CommandTextSource",)
-__description__ = _("Run commandline programs")
+__description__ = _(u"Run command-line programs. Actions marked with"
+                    u" the symbol %s run in a subshell.") % u"\N{GEAR}"
 __version__ = ""
 __author__ = "Ulrik Sverdrup <ulrik sverdrup gmail com>"
 
 import os
-import shlex
 
 import gobject
 
@@ -23,31 +23,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 +46,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 +60,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 +73,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 +107,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 +119,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 +148,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 +162,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):
@@ -230,4 +211,4 @@ class CommandTextSource (TextSource):
 				yield Command(exepath, text)
 				break
 	def get_description(self):
-		return _("Run commandline programs")
+		return _("Run command-line programs")



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