diff --git a/lib/utils/__init__.py b/lib/utils/__init__.py
index f31d52909349475f3c379934bb70398de24aeb40..d808ce44dabc1404bc7fdd6ea64ad0d47ab3a043 100644
--- a/lib/utils/__init__.py
+++ b/lib/utils/__init__.py
@@ -73,9 +73,6 @@ _VALID_SERVICE_NAME_RE = re.compile("^[-_.a-zA-Z0-9]{1,128}$")
 UUID_RE = re.compile('^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-'
                      '[a-f0-9]{4}-[a-f0-9]{12}$')
 
-#: Shell param checker regexp
-_SHELLPARAM_REGEX = re.compile(r"^[-a-zA-Z0-9._+/:%@]+$")
-
 
 def ForceDictType(target, key_types, allowed_values=None):
   """Force the values of a dict to have certain types.
@@ -232,47 +229,6 @@ def TryConvert(fn, val):
   return nv
 
 
-def IsValidShellParam(word):
-  """Verifies is the given word is safe from the shell's p.o.v.
-
-  This means that we can pass this to a command via the shell and be
-  sure that it doesn't alter the command line and is passed as such to
-  the actual command.
-
-  Note that we are overly restrictive here, in order to be on the safe
-  side.
-
-  @type word: str
-  @param word: the word to check
-  @rtype: boolean
-  @return: True if the word is 'safe'
-
-  """
-  return bool(_SHELLPARAM_REGEX.match(word))
-
-
-def BuildShellCmd(template, *args):
-  """Build a safe shell command line from the given arguments.
-
-  This function will check all arguments in the args list so that they
-  are valid shell parameters (i.e. they don't contain shell
-  metacharacters). If everything is ok, it will return the result of
-  template % args.
-
-  @type template: str
-  @param template: the string holding the template for the
-      string formatting
-  @rtype: str
-  @return: the expanded command line
-
-  """
-  for word in args:
-    if not IsValidShellParam(word):
-      raise errors.ProgrammerError("Shell argument '%s' contains"
-                                   " invalid characters" % word)
-  return template % args
-
-
 def ParseCpuMask(cpu_mask):
   """Parse a CPU mask definition and return the list of CPU IDs.
 
diff --git a/lib/utils/text.py b/lib/utils/text.py
index af42d368020ba8b6921396100b124d108fb56143..c51d7292c7dde2965b5df07cd630add3b87ed07f 100644
--- a/lib/utils/text.py
+++ b/lib/utils/text.py
@@ -40,6 +40,9 @@ _SHELL_UNQUOTED_RE = re.compile('^[-.,=:/_+@A-Za-z0-9]+$')
 #: MAC checker regexp
 _MAC_CHECK_RE = re.compile("^([0-9a-f]{2}:){5}[0-9a-f]{2}$", re.I)
 
+#: Shell param checker regexp
+_SHELLPARAM_REGEX = re.compile(r"^[-a-zA-Z0-9._+/:%@]+$")
+
 
 def MatchNameComponent(key, name_list, case_sensitive=True):
   """Try to match a name against a list.
@@ -442,3 +445,44 @@ class LineSplitter:
     self.flush()
     if self._buffer:
       self._line_fn(self._buffer)
+
+
+def IsValidShellParam(word):
+  """Verifies is the given word is safe from the shell's p.o.v.
+
+  This means that we can pass this to a command via the shell and be
+  sure that it doesn't alter the command line and is passed as such to
+  the actual command.
+
+  Note that we are overly restrictive here, in order to be on the safe
+  side.
+
+  @type word: str
+  @param word: the word to check
+  @rtype: boolean
+  @return: True if the word is 'safe'
+
+  """
+  return bool(_SHELLPARAM_REGEX.match(word))
+
+
+def BuildShellCmd(template, *args):
+  """Build a safe shell command line from the given arguments.
+
+  This function will check all arguments in the args list so that they
+  are valid shell parameters (i.e. they don't contain shell
+  metacharacters). If everything is ok, it will return the result of
+  template % args.
+
+  @type template: str
+  @param template: the string holding the template for the
+      string formatting
+  @rtype: str
+  @return: the expanded command line
+
+  """
+  for word in args:
+    if not IsValidShellParam(word):
+      raise errors.ProgrammerError("Shell argument '%s' contains"
+                                   " invalid characters" % word)
+  return template % args
diff --git a/test/ganeti.utils.text_unittest.py b/test/ganeti.utils.text_unittest.py
index 9af51b3900b1f3aea8589b67aa58b9110b91b070..2bc0c23b4d9ed8dfd0b8a9b59a93e143966e8e59 100755
--- a/test/ganeti.utils.text_unittest.py
+++ b/test/ganeti.utils.text_unittest.py
@@ -422,5 +422,21 @@ class TestLineSplitter(unittest.TestCase):
                              "", "x"])
 
 
+class TestIsValidShellParam(unittest.TestCase):
+  def test(self):
+    for val, result in [
+      ("abc", True),
+      ("ab;cd", False),
+      ]:
+      self.assertEqual(utils.IsValidShellParam(val), result)
+
+
+class TestBuildShellCmd(unittest.TestCase):
+  def test(self):
+    self.assertRaises(errors.ProgrammerError, utils.BuildShellCmd,
+                      "ls %s", "ab;cd")
+    self.assertEqual(utils.BuildShellCmd("ls %s", "ab"), "ls ab")
+
+
 if __name__ == "__main__":
   testutils.GanetiTestProgram()
diff --git a/test/ganeti.utils_unittest.py b/test/ganeti.utils_unittest.py
index 661be9a024edbc975ab25206a7e3e4f6a299fddb..84c96c764d0abc5aa3fc0e4d73a87ec8c3eca720 100755
--- a/test/ganeti.utils_unittest.py
+++ b/test/ganeti.utils_unittest.py
@@ -305,21 +305,5 @@ class TestTryConvert(unittest.TestCase):
       self.assertEqual(utils.TryConvert(fn, src), result)
 
 
-class TestIsValidShellParam(unittest.TestCase):
-  def test(self):
-    for val, result in [
-      ("abc", True),
-      ("ab;cd", False),
-      ]:
-      self.assertEqual(utils.IsValidShellParam(val), result)
-
-
-class TestBuildShellCmd(unittest.TestCase):
-  def test(self):
-    self.assertRaises(errors.ProgrammerError, utils.BuildShellCmd,
-                      "ls %s", "ab;cd")
-    self.assertEqual(utils.BuildShellCmd("ls %s", "ab"), "ls ab")
-
-
 if __name__ == '__main__':
   testutils.GanetiTestProgram()