docs: def main(argv=None):
      """
      Script entry point
  
      :param argv: Script arguments (None for sys.argv)
      :return: An exit code or None
      """
      # Prepare arguments
      parser = argparse.ArgumentParser(
          prog="pelix.shell.remote",
          parents=[make_common_parser()],
          description="Pelix Remote Shell ({} SSL support)".format(
              "with" if ssl is not None else "without"
          ),
      )
  
      # Remote shell options
      group = parser.add_argument_group("Remote Shell options")
      group.add_argument(
          "-a",
          "--address",
          default="localhost",
          help="The remote shell binding address",
      )
      group.add_argument(
          "-p",
          "--port",
          type=int,
          default=9000,
          help="The remote shell binding port",
      )
  
      if ssl is not None:
          # Remote Shell TLS options
          group = parser.add_argument_group("TLS Options")
          group.add_argument("--cert", help="Path to the server certificate file")
          group.add_argument(
              "--key",
              help="Path to the server key file "
              "(can be omitted if the key is in the certificate)",
          )
          group.add_argument(
              "--key-password",
              help="Password of the server key."
              "Set to '-' for a password request.",
          )
          group.add_argument(
              "--ca-chain",
              help="Path to the CA chain file to authenticate clients",
          )
  
      # Local options
      group = parser.add_argument_group("Local options")
      group.add_argument(
          "--no-input",
          action="store_true",
          help="Run without input (for daemon mode)",
      )
  
      # Parse them
      args = parser.parse_args(argv)
  
      # Handle arguments
      init = handle_common_arguments(args)
  
      # Set the initial bundles
      bundles = [
          "pelix.ipopo.core",
          "pelix.shell.core",
          "pelix.shell.ipopo",
          "pelix.shell.remote",
      ]
      bundles.extend(init.bundles)
  
      # Start a Pelix framework
      framework = pelix.framework.create_framework(
          utilities.remove_duplicates(bundles), init.properties
      )
      framework.start()
      context = framework.get_bundle_context()
  
      # Instantiate configured components
      init.instantiate_components(framework.get_bundle_context())
  
      # Instantiate a Remote Shell, if necessary
      with use_ipopo(context) as ipopo:
          rshell_name = "remote-shell"
          try:
              ipopo.get_instance_details(rshell_name)
          except ValueError:
              # Component doesn't exist, we can instantiate it.
  
              if ssl is not None:
                  # Copy parsed arguments
                  ca_chain = args.ca_chain
                  cert = args.cert
                  key = args.key
  
                  # Normalize the TLS key file password argument
                  if args.key_password == "-":
                      import getpass
  
                      key_password = getpass.getpass(
                          "Password for {}: ".format(args.key or args.cert)
                      )
                  else:
                      key_password = args.key_password
              else:
                  # SSL support is missing:
                  # Ensure the SSL arguments are defined but set to None
                  ca_chain = None
                  cert = None
                  key = None
                  key_password = None
  
              # Setup the component
              rshell = ipopo.instantiate(
                  pelix.shell.FACTORY_REMOTE_SHELL,
                  rshell_name,
                  {
                      "pelix.shell.address": args.address,
                      "pelix.shell.port": args.port,
                      "pelix.shell.ssl.ca": ca_chain,
                      "pelix.shell.ssl.cert": cert,
                      "pelix.shell.ssl.key": key,
                      "pelix.shell.ssl.key_password": key_password,
                  },
              )
  
              # Avoid loose reference to the password
              del key_password
          else:
              logging.error(
                  "A remote shell component (%s) is already "
                  "configured. Abandon.",
                  rshell_name,
              )
              return 1
  
      # Prepare a banner
      host, port = rshell.get_access()
      try:
          if args.no_input:
              # No input required: just print the access to the shell
              print("Remote shell bound to:", host, "- port:", port)
  
              try:
                  while not framework.wait_for_stop(1):
                      # Awake from wait every second to let KeyboardInterrupt
                      # exception to raise
                      pass
              except KeyboardInterrupt:
                  print("Got Ctrl+C: exiting.")
                  return 127
          else:
              # Prepare interpreter variables
              variables = {
                  "__name__": "__console__",
                  "__doc__": None,
                  "__package__": None,
                  "framework": framework,
                  "context": context,
                  "use_ipopo": use_ipopo,
              }
  
              banner = (
                  "{lines}\nPython interpreter with Pelix Remote Shell\n"
                  "Remote shell bound to: {host}:{port}\n{lines}\n"
                  "Python version: {version}\n".format(
                      lines="-" * 80, version=sys.version, host=host, port=port
                  )
              )
  
              # Run an interpreter
              _run_interpreter(variables, banner)
      finally:
          # Stop the framework
          framework.stop()