【问题标题】:How to emulate a ctrl sequence with `system()`?如何使用 `system()` 模拟 ctrl 序列?
【发布时间】:2017-12-24 01:43:06
【问题描述】:

如果我在终端 (LINUX) 中使用 CTRL + A CTRL + K,它会清除我在终端中输入的行。我想通过我的代码中的system() 调用来执行此功能。我应该将哪些参数传递给 system() 以使其运行 CTRL + A CTRL + K?

【问题讨论】:

    标签: c linux parameters command-line-interface terminal-emulator


    【解决方案1】:

    如果您只想清除当前行作为您的应用程序的输出并将光标移到开头,则不需要使用system();而是使用printf。代码\r 表示回车,将光标移动到行首,ANSI 转义序列CSI 2 K 将清除整行 - CSI 由 2 个字符组成:ASCII ESC (\033),和[.

    因此:

    #include <stdio.h>
    #include <unistd.h>
    
    int main(void) {
        printf("Here be demo");
        fflush(stdout);
        sleep(1);
        printf("\r\033[2KIt works!\n");
    }
    

    【讨论】:

      【解决方案2】:

      你很可能试图做错事。

      首先要注意一点,您可以仅使用 ^U 清除该行。 ^K 删除当前位置的内容,^A 将您带到开头,这是一种迂回的方式。

      大多数程序不应该接受交互式输入,而是从命令行获取参数(argc 和 argv 的东西)。在不太可能的情况下,程序必须是交互式的,您通常不想进行任何显式的屏幕操作。在更不可能的情况下,进行上述操作是有意义的,您想使用 ncurses 之类的东西。

      也就是说,我强烈建议您详细说明您的实际问题。

      【讨论】:

        【解决方案3】:

        这没有意义,但是您可以在system() 中使用 Ctrl+A Ctrl+K,方法是编写一个分配 PTY 的命令,运行像 bash 这样的 readline 命令,然后将 ASCII 0x01 0x0B 写入它。 scriptprintf 让您可以这样做:

        void main() {
          system(
              "{ sleep 1; "
              "echo -n 'part of a line. deleting with Ctrl+A Ctrl+K soon...'; "
              "sleep 3; "
              "printf '\x01\x0b'; "
              "sleep 2; "
              "} | script -q 'bash'"
              );
        }
        

        这将显示一个 bash 提示符,模拟写入“部分行..”,然后将 Ctrl-A Ctrl-K 写入其中,将其删除。

        确保在不做任何更改的情况下逐字尝试,因为它无法适应在更大的程序中做任何有用的事情。

        PS:如果你想写和覆盖一行来创建一个微调器或进度条,你应该问的问题是“我如何写和覆盖一行来创建一个微调器或进度条?”

        【讨论】:

        • 我对这个答案感到困惑。怀疑他们只是想制作某种进度条或微调器可能是正确的,并且有一个合理/琐碎的答案,而您选择不提供。相反,您提供了一个明显疯狂的代码示例,实现了 OP 的错误想法,现在冒着他们会在此基础上构建一些东西的风险。
        • 技术上正确是最好的正确 ^__^
        【解决方案4】:

        首先检查这些命令给出的终端控制序列。您可以通过在命令前按 CTRL + V 来执行此操作。你可能会得到

        ^A^K
        

        如果您想通过system() 调用来执行此操作,那么您应该使用它调用一个命令,这会将这个终端控制序列弹出到您的屏幕上。最简单的命令是/bin/echo。一个

        /bin/echo -ne '^A^K'
        

        也会这样做。给system()

        system("/bin/echo -ne '^A^K'");
        

        并且想知道。

        【讨论】:

        • 我试过了,这只是在我的命令行中打印出“^A^K”
        • @Aria 这是echo-e。是evaluate的缩写。
        • 等等,这行清楚是你的shell或终端模拟器的特性,那真的没那么容易!但是试一试。如果还是不行,下一步就要搞清楚了,这个行删除功能有什么作用。
        • echo -e 不适用于插入符号,将这些字符写入屏幕不会影响 bash 的行阅读。
        • @thatotherguy 1. 然后尝试echo -e,您会发现它有效。 2. 这是一个不同的(子)问题,这个序列会做什么。在我解释的comment 中,它肯定不会起作用。 3.我不知道是什么使这个序列的行删除,bash(即readline)或任何东西,OP没有写它。
        猜你喜欢
        • 2013-01-01
        • 2015-08-05
        • 1970-01-01
        • 2015-07-16
        • 1970-01-01
        • 2013-03-15
        • 2023-03-31
        • 2016-02-17
        • 2010-12-23
        相关资源
        最近更新 更多