【问题标题】:termcap of program executed between backticks在反引号之间执行的程序的 termcap
【发布时间】:2017-06-23 13:52:20
【问题描述】:

我正在尝试制作一个 C 程序来选择选项。如果我这样运行它就可以了:

./select choice{1..5}
☐ choice1  ☐ choice3  ☐ choice5
☐ choice2  ☐ choice4

# outputs "choice1 choice2" on stdout

但如果我在反引号之间运行它,那就太糟糕了

`./select choice{1..5}` > choices.txt
☐ choice1☐ choice2☐ choice3☐ choice4☐ choice5

# Write "choice1 choice2" in `choices.txt`

我需要能够检索选定的选项。这就是为什么我将所有输出都输出到我打开的文件中

int tty = open("/dev/tty", O_RDWR);
/* Do my program using outputs on fd `tty` */
printf("%s\n", get_results());

我认为这与在我的代码中使用tgoto 来移动屏幕上的书写光标有关。

if ((cm = tgetstr("cm", NULL)) == NULL)
    return (-1);
tputs(tgoto(cm, x, y), fd, &my_putchar);
return (0);

我已经看到使用 isatty(1) 在反引号之间执行时返回 0,如果直接执行则返回 1...那么,有没有办法让我在两种情况下移动光标并保持格式?

感谢您的宝贵时间

【问题讨论】:

  • 只有我一个人,还是这个问题完全不清楚? shell中编译后的二进制文件的调用与代码本身有什么关系?
  • 因为它以某种方式改变了上下文,从而改变了程序的行为。然后它输出不同,这对我来说是个问题。
  • 它不会改变程序的行为。唯一改变的是你的输出方式。当您将其分配给变量然后echo 时,您可以通过shell 对其进行的任何操作对其进行过滤。
  • 好吧,其实我在反引号之间显示的用例是模棱两可的,我修好了
  • tputs() 将只输出一个转义序列(以转义字符开头的字符序列),您的终端通过移动光标来解释它。当然,当您自己捕获输出时,这不会按预期工作。如果您需要包含结构的纯文本,则必须找到一种无需“光标移动”即可生成它的方法。

标签: c bash tty backticks termcap


【解决方案1】:

问题中显示的代码片段正在使用 termcap 接口(不是 curses)。它使用

tputs(tgoto(cm, x, y), fd, &my_putchar);

其中 my_putchar 可能像程序的其余部分一样写入标准输出(使用 printf)。如果程序被修改为将其所有屏幕输出写入标准错误,那么最后它可以将其结果写入标准输出,从而简化脚本。

无需打开/dev/tty;而是替换

printf("choice%d", n);

通过

fprintf(stderr, "choice%d", n);

当然还有将 my_putchar 改为类似

int my_putchar(int c) { return fputc(c, stderr); }

是要走的路。

如果这是一个 curses 应用程序,可以使用newterm 而不是initscr 来更改输出流。 dialog 使用 newterm,当然。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-28
    • 2013-07-21
    • 1970-01-01
    • 1970-01-01
    • 2019-06-13
    • 1970-01-01
    • 1970-01-01
    • 2012-04-25
    相关资源
    最近更新 更多