Python Encapsulation shell Command Instance analysis

Source: Internet
Author: User
Tags exit sleep ssh

The examples in this article describe how Python encapsulates the shell command. Share to everyone for your reference. The implementation methods are as follows:

?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26-27--28 29---30 31--32 33 34 35 36 37 38-39 40 41 42 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 5, 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 11 9 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148-149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179-18 0 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203-204 #-*-coding:utf-8-*-import OS import subprocess Import signal import PWD Import sys class Mocklogger (object): ' Simulate log Class. Facilitates unit testing. ' Def __init__ (self): Self.info = Self.error = self.critical = Self.debug def debug (Self, msg): print "LOGGER:" +msg clas s Shell (object): "To complete the packaging of the shell script." The execution results are stored in Shell.ret_code, Shell.ret_info, Shell.err_info, and run () is a normal call that waits for the Shell command to return. Run_background () is an asynchronous call and returns immediately without waiting for the shell command to complete the asynchronous call, either by using the Get_status () query state, or by using wait () to enter the blocking state. When invoked asynchronously, the Kill () is used to force the script to stop, and you still need to wait for the actual exit. TODO does not validate the case when the shell command contains an oversized result output. ' Def __init__ (self, cmd): self.cmd = cmd # cmd includes commands and parameters Self.ret_code = None Self.ret_info = None Self.err_info = None #使 Can be replaced with a specific logger Self.logger = Mocklogger () def run_background (self): ' Executes the shell command in a non-blocking manner (the default way for Popen). ' Self.logger.debug (' run%s '%self.cmd) # Popen throws a OSError exception when the command to be executed does not exist, but after Shell=true, the # Shell handles errors that are not present in the command. Therefore, there is no oserror anomaly, so it is not necessary to deal with self._process = subprocess. Popen (Self.cmd, Shell=true, stdout=subprocess. PIPE, Stderr=subprocess. PIPE) #非阻塞 def run(self): ' Executes the shell command in a blocking manner. ' Self.run_background () self.wait () def run_cmd (self, cmd): ' Execute a command directly. Convenient for one instance to repeat the execution of multiple commands. ' Self.cmd = cmd self.run () def wait (self): ' Waits for shell execution to complete. ' Self.logger.debug ("waiting%s"%self.cmd) self.ret_info, self.err_info = Self._process.communicate () #阻塞 # Returncode:a Negative value-n Indicates the child is # terminated by signal N Self.ret_code = Self._process.return Code self.logger.debug ("waiting%s done.) Return code is%d% (Self.cmd, Self.ret_code)) def get_status (self): ' Get script run state (running| Finished) ' Retcode = Self._process.poll () if Retcode = = None:status = "RUNNING" Else:status = "finished" Self.logger. Debug ('%s ' is%s '% (self.cmd, status) return to status # Python2.4 's subprocess hasn't Send_signal,terminate,kill # So here's a cottage, 2.7 can be directly with Self._process Kill () def send_signal (self, SIG): Self.logger.debug ("Send signal%s to%s"% (SIG, Self.cmd) Os.kill (Self._process.pid, SIG) def terminate (self): self.send_signal (signal. Sigterm def Kill (self): Self.send_signal (signal. SIGKILL def print_result (self): print "Return code:", Self.ret_code print "return info:", self.ret_info print "Error inf O: ", Self.err_info class Remoteshell (Shell):" Remote command (SSH mode). XXX commands with special characters may cause calls to fail, such as double quotes, $ $ Note If CMD contains double quotes, you can use RemoteShell2 ' Def __init__ (self, cmd, IP): SSH = ("Ssh-o Preferredaut Hentications=publickey-o "" "Stricthostkeychecking=no-o connecttimeout=10") # Do not need to check IP validity, do not need to check the trust relationship, there is a problem shell will error cmd = '%s ' %s '%s '% (SSH, IP, cmd) shell.__init__ (self, CMD) class RemoteShell2 (Remoteshell): "" is the same as Remoteshell, except that the quotes are transformed. ' Def __init__ (self, cmd, IP): remoteshell.__init__ (self, cmd, IP) self.cmd = "%s%s '%s '"% (SSH, IP, cmd) class Sushell ( Shell): "Toggle User Execution Command (SU method). XXX is only suitable to use root to switch to other users. Because the other switch user needs to enter a password, so the program will hang. XXX commands with special characters may cause calls to fail, such as double quotes, $ $ Note If CMD contains double quotes, you can use SuShell2 ' Def __init__ (self, cmd, user): If Os.getuid ()!= 0: # Non-root User Direct error raise Exception (' Sushell must to called by Root user! ') cmd = ' Su-%s-c '%s '% (user, cmd) shell.__init__ (self, CMD) class SuShell2 (Sushell): "" and Sushell is the same, just the change in quotes. ' Def __init__ (self, cmd, user): Sushell.__init__ (self, cmd, user) Self.cmd = "Su-%s-c '%s '"% (user, cmd) class Sushel Ldeprecated (Shell): "Switch User execution commands (setuid). The function executed is run2 instead of run XXX running in an "unclean" way: Only users and groups are switched, and the environment variable information is unchanged. XXX cannot get command ret_code, ret_info, err_info xxx is only suitable to use root to switch to other users. ' Def __init__ (self, cmd, user): Self.user = user shell.__init__ (self, cmd) def run2 (self): if Os.getuid ()!= 0: # Non-root User Direct error raise Exception (' SuShell2 must be called by Root user! ') Child_pid = Os.fork () If child_pid = 0: # subprocess work uid, GID = Pwd.getpwnam (Self.user) [2:4] Os.setgid (GID) # must set group Os.setuid (UID) self.run () sys.exit (0) # subprocess exit to prevent further code execution else: # Parent The process waits for the subprocess to exit Os.waitpid (child_pid, 0) If __name__ = = "__main__": ' Test Code ' # 1. Test normal SA = Shell (' Who ') Sa.run () Sa.print_result () # 2. Test stderr sb = Shell (' ls/export/dir_should_not_exists ') Sb.run () Sb.print_result () # 3. Test background sc = Shell (' Sleep 1 ') Sc.run_background () print ' HEllo from parent process ' print ' Return code: ", Sc.ret_code print" Status: ", Sc.get_status () sc.wait () Sc.print_result () # 4. Test Kill import Time SD = Shell ("Sleep 2") Sd.run_background () time.sleep (1) Sd.kill () sd.wait () # Note, still need t o Wait Sd.print_result () # 5. Test multiple command and uncompleted command output SE = Shell (' pwd;sleep 1;pwd;pwd ') se.run_background () Time.sleep (1) s E.kill () se.wait () # Note, still need to wait Se.print_result () # 6. Test wrong command SF = Shell (' aaaaa ') Sf.run () Sf.print_result () # 7. Test instance reuse to run other command sf.cmd = ' echo aaaaa ' Sf.run () sf.print_result () sg = Remoteshell (' pwd ', ' 127.0.0 .1 ') Sg.run () Sg.print_result () # unreachable IP SG2 = Remoteshell (' pwd ', ' 17.0.0.1 ') Sg2.run () Sg2.print_result () # inval ID IP sg3 = Remoteshell (' pwd ', ' 1711.0.0.1 ') Sg3.run () Sg3.print_result () # IP without trust relation SG3 = Remoteshell (' P WD ', ' 10.145.132.247 ') Sg3.run () sg3.print_result () sh = Sushell (' pwd ', ' Ossuser ') Sh.run () Sh.priNt_result () # wrong user Si = Sushell (' pwd ', ' ossuser123 ') Si.run () Si.print_result () # user need password si = Sushell (' P WD ', ' root ') Si.run () Si.print_result ()

I hope this article will help you with your Python programming.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.