public void run() throws Exception {
        final Terminal terminal = TerminalBuilder.builder()
                .nativeSignals(true)
                .signalHandler(signal -> {
                    if (signal == Terminal.Signal.INT || signal == Terminal.Signal.QUIT) {
                        if (execState == ExecState.RUNNING) {
                            throw new InterruptShellException();
                        } else {
                            exit(0);
                        }
                    }
                })
                .build();
        run((providersMap) -> {
            String serviceUrl = "";
            String adminUrl = "";
            for (ShellCommandsProvider provider : providersMap.values()) {
                final String providerServiceUrl = provider.getServiceUrl();
                if (providerServiceUrl != null) {
                    serviceUrl = providerServiceUrl;
                }
                final String providerAdminUrl = provider.getAdminUrl();
                if (providerAdminUrl != null) {
                    adminUrl = providerAdminUrl;
                }
            }

            LineReaderBuilder readerBuilder = LineReaderBuilder.builder()
                    .terminal(terminal)
                    .parser(parser)
                    .completer(systemRegistry.completer())
                    .variable(LineReader.INDENTATION, 2)
                    .option(LineReader.Option.INSERT_BRACKET, true);

            configureHistory(properties, readerBuilder);
            LineReader reader = readerBuilder.build();

            final String welcomeMessage =
                    String.format("Welcome to Pulsar shell!\n  %s: %s\n  %s: %s\n\n"
                                    + "Type %s to get started or try the autocompletion (TAB button).\n"
                                    + "Type %s or %s to end the shell session.\n",
                            new AttributedStringBuilder().style(AttributedStyle.BOLD).append("Service URL").toAnsi(),
                            serviceUrl,
                            new AttributedStringBuilder().style(AttributedStyle.BOLD).append("Admin URL").toAnsi(),
                            adminUrl,
                            new AttributedStringBuilder().style(AttributedStyle.BOLD).append("help").toAnsi(),
                            new AttributedStringBuilder().style(AttributedStyle.BOLD).append("exit").toAnsi(),
                            new AttributedStringBuilder().style(AttributedStyle.BOLD).append("quit").toAnsi());
            output(welcomeMessage, terminal);
            String promptMessage;
            if (configShell.getCurrentConfig() != null) {
                promptMessage = String.format("%s(%s)",
                        configShell.getCurrentConfig(), getHostFromUrl(serviceUrl));
            } else {
                promptMessage = getHostFromUrl(serviceUrl);
            }
            final String prompt = createPrompt(promptMessage);
            return new InteractiveLineReader() {
                @Override
                public String readLine() {
                    return reader.readLine(prompt);
                }

                @Override
                public List<String> parseLine(String line) {
                    return reader.getParser().parse(line, 0).words();
                }
            };
        }, () -> terminal);
    }
@Test
    public void testFileModeExitOnError() throws Exception {
        Terminal terminal = TerminalBuilder.builder().build();
        final MockLineReader linereader = new MockLineReader(terminal);
        final Properties props = new Properties();
        props.setProperty("webServiceUrl", "http://localhost:8080");

        final String shellFile = Thread.currentThread()
                .getContextClassLoader().getResource("test-shell-file-error").getFile();

        final TestPulsarShell testPulsarShell = new TestPulsarShell(new String[]{"-f", shellFile, "--fail-on-error"},
                props, pulsarAdmin);
        try {
            testPulsarShell.run((a) -> linereader, () -> terminal);
            fail();
        } catch (SystemExitCalledException ex) {
            assertEquals(ex.code, 1);
        }

        verify(topics).createNonPartitionedTopic(eq("persistent://public/default/my-topic"), any(Map.class));
        verify(testPulsarShell.cmdProduceHolder.get(), times(0)).run();
    }