2929import platform
3030import fileinput
3131import re
32+ import pwd
3233from datetime import datetime
3334from clint .textui import colored , prompt
3435import adafruit_platformdetect
@@ -65,7 +66,9 @@ def select_n(message, selections):
6566 )
6667 return prompt .options (message , options )
6768
68- def run_command (self , cmd , suppress_message = False , return_output = False ):
69+ def run_command (
70+ self , cmd , suppress_message = False , return_output = False , run_as_user = None
71+ ):
6972 """
7073 Run a shell command and show the output as it runs
7174 """
@@ -79,13 +82,31 @@ def read_stream(output):
7982 except TypeError :
8083 return ""
8184
85+ # Allow running as a different user if we are root
86+ if self .is_root () and run_as_user is not None :
87+ pw_record = pwd .getpwnam (run_as_user )
88+ env = os .environ .copy ()
89+ env ["HOME" ] = pw_record .pw_dir
90+ env ["LOGNAME" ] = run_as_user
91+ env ["USER" ] = pw_record .pw_name
92+
93+ def preexec ():
94+ os .setgid (pw_record .pw_gid )
95+ os .setuid (pw_record .pw_uid )
96+
97+ else :
98+ env = None
99+ preexec = None
100+
82101 full_output = ""
83- with subprocess .Popen (
102+ with subprocess .Popen ( # pylint: disable=subprocess-popen-preexec-fn
84103 cmd ,
85104 shell = True ,
86105 stdout = subprocess .PIPE ,
87106 stderr = subprocess .PIPE ,
88107 universal_newlines = True ,
108+ env = env ,
109+ preexec_fn = preexec ,
89110 ) as proc :
90111 while proc .poll () is None :
91112 err = read_stream (proc .stderr )
@@ -203,9 +224,9 @@ def chdir(self, directory):
203224 # directory = self.getcwd() + "/" + directory
204225 directory = self .path (directory )
205226 if not self .exists (directory ):
206- raise ValueError ("Directory does not exist" )
227+ raise ValueError (f "Directory ' { directory } ' does not exist" )
207228 if not self .isdir (directory ):
208- raise ValueError ("Given location is not a directory" )
229+ raise ValueError (f"The given location ' { directory } ' is not a directory" )
209230 os .chdir (directory )
210231
211232 def pushd (self , directory ):
0 commit comments