code: def run(self):
      shell = os.environ.get("SHELL", "/bin/sh")
  
      self.process = subprocess.Popen(
          self.command,
          # [shell, '-i', '-c', self.command],
          encoding="utf-8",
          stdout=subprocess.PIPE,
          stderr=subprocess.PIPE,
          shell=True,
          env=os.environ.copy(),
          executable=shell,
          bufsize=0,
      )
  
      while True:
          self._read_stdout()
          self._read_stderr()
          if self.process.poll() is not None:
              break
          time.sleep(0.1)
      self.exit_code = self.process.returncode
  
      self._read_stdout()
      self._read_stderr()
  
imports: import argparse
  import os
  import subprocess
  import sys
  import threading
  import time
  from typing import List
  from labml import logger, experiment
  from labml.experiment import generate_uuid
  from labml.internal.app import AppTracker, SimpleAppTrackDataSource
  from labml.internal.app.logs import AppConsoleLogs
  from labml.internal.app.url import AppUrlResponseHandler
  from labml.internal.lab import get_app_url_for_handle
  from labml.logger import Text
  from labml.utils.validators import ip_validator
label_desc: Use image node_id 5 for calling the ExecutorThread obj's underlying member method code with example usage: obj.run() without return types