我想知道如何更改以下行为.假设我的终端有28条线路.然后我使用以下命令:
$ tput lines # my terminal
28
$ docker run --rm -it ubuntu:16.04 tput lines # docker container
24 ## WHY??
$ docker run --rm -it ubuntu:16.04 bash # docker container inside command
root@810effa2777c:/# tput lines
28
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,即使所有结果都应该是28,当我调用容器时,docker run --rm -it ubuntu:16.04 tput lines
尽管我的终端大小,它总是给我24.这不仅仅是ubuntu容器,我也尝试过使用debian(docker run --rm -it debian tput lines
)并且我得到了相同的结果24.
这样做的目的是使用mdp演示工具,它考虑了终端中的行.当我的实现失败时,我尝试了其他人的docker实现,但我遇到了同样的错误.
这是我在图像中的错误:
有谁知道它可能是什么以及如何解决这个问题?
我们有一个由CRON运行的shell脚本.shell脚本依次运行python脚本,该脚本从FTP服务器下载文件,然后在这些文件上运行java日志处理器.这个过程运行得很好,除非我没有错误地继续收到CRON电子邮件.至少,我认为没有错误.cron电子邮件有两行,其中一行是
tput: No value for $TERM and no -T specified
Run Code Online (Sandbox Code Playgroud)
经过一番研究后,我发现它与设置$ TERM变量有关.我不确定,怎么做.任何帮助,将不胜感激.谢谢!
虽然我知道tput rmcup
从“备用屏幕”(在 中称为“杯子模式” man 5 terminfo
)返回并恢复保存的屏幕,但它确实具有重新定位光标的副作用。
因此,如果tput smcup
被调用,tput rmcup
则恢复屏幕并重新定位光标,但如果您随后再键入一些命令或按 Enter 几次然后再次使用tput rmcup
,光标将返回到原始保存的位置。
一个用例是在bash
重播终端录音的脚本中[使用scriptreplay
]:如果脚本提前结束而没有[相当于]调用tput rmcup
,那么我希望能够在我的bash
脚本中检测到这一点并tput rmcup
自动调用。
简而言之,我希望能够确定当前的屏幕状态是什么;即,它是“备用屏幕”还是“正常屏幕”?
我正在尝试创建一个可更新的进度状态。为了做到这一点,我需要能够完全清除最后一个输出,以便我可以更新它。回车可以工作,但是当输出超过终端宽度并回绕时,将无法清除最后一个输出。所以我正在使用 tput:
n=0
while [[ $n -ne 100 ]]; do
n=$((n+1))
tput ed #clear
tput sc #save cursor
echo -n "Progress: ${n}%"
tput rc #restore cursor
sleep 1s
done
echo
Run Code Online (Sandbox Code Playgroud)
但是,如果输出足够长以致于强制终端向上滚动,这将失败。发生这种情况时,保存的光标位置不再正确,并且无法正确清除最后的输出。
例如,如果光标当前在终端的底部并且输出比终端宽度长,则会强制终端向上滚动,使之前保存的光标位置无效。
那么有没有什么办法可以保证Bash中的光标永远不会到终端结束呢?或者也许还有其他一些替代方法来防止这个问题?
编辑:我根据 F. Hauri 的回答制作了我自己的版本,简化了我的用例
#!/bin/bash
str=$(head -c 338 < /dev/zero | tr '\0' '\141')
len="${#str}"
col=$(tput cols)
lines=$(( ((len + col - 1) / col) - 1 ))
echo -ne "${str}\r"
(( len > col )) && tput cuu "$lines"
sleep 3s
tput ed
Run Code Online (Sandbox Code Playgroud) 我正在寻找包含此内容的文件
export fgBlack8="$(tput setf 0)";
export fgRed8="$(tput setf 1)";
export fgGreen8="$(tput setf 2)";
export fgYellow8="$(tput setf 3)";
export fgBlue8="$(tput setf 4)";
export fgMagenta8="$(tput setf 5)";
export fgCyan8="$(tput setf 6)";
export fgWhite8="$(tput setf 7)";
export bgBlack8="$(tput setb 0)";
export bgRed8="$(tput setb 1)";
export bgGreen8="$(tput setb 2)";
export bgYellow8="$(tput setb 3)";
export bgBlue8="$(tput setb 4)";
export bgMagenta8="$(tput setb 5)";
export bgCyan8="$(tput setb 6)";
export bgWhite8="$(tput setb 7)";
Run Code Online (Sandbox Code Playgroud)
根据此链接:https://linux.101hacks.com/ps1-examples/prompt-color-using-tput/
然后,当用这样的几个命令测试颜色时
echo -e "${fgBlack8}fgBlack8"
echo -e "${fgRed8}fgRed8"
echo -e "${fgGreen8}fgGreen8"
echo -e "${fgYellow8}fgYellow8" …
Run Code Online (Sandbox Code Playgroud) 几个* NIX命令,比如screen
,man
,vim
和其他人,创建一个临时帆布/屏幕/在shell环境的覆盖。当此类程序执行时,它们会覆盖或隐藏之前在终端中显示的任何内容——几乎就像终端窗口内的“全屏”模式。然而,当它们终止时,它们会显示或恢复之前在终端上的任何内容。
在下面的示例中,我在屏幕上创建了一些填充文本,然后调用man bash
. 手册页打开并覆盖终端显示屏上的所有其他字符。当我关闭手册页时,被覆盖的字符再次显示。
我希望写入 stdout/stderr 的程序可以完成第一步(用程序特定的内容替换终端的内容),但随后它会产生大量我可以滚动浏览的文本,因此无法执行第二步:恢复终端内容。这意味着程序以某种方式记住屏幕的先前内容并重新输出它们(我怀疑它?),或者它在终端内创建某种子窗口,并且其他东西跟踪终端的先前内容.
我怎样才能在我自己的程序和/或脚本中实现这种行为?
也许我应该使用curses/ncurses、tput、termcap/terminfo 或ANSI 转义序列?
这个修改后的问题与https://unix.stackexchange.com/questions/27941/show-output-on-another-screen-and-return-to-normal-when-done基本相同。(尽管进行了大量搜索,但我在写这个问题时还没有找到它。)不同之处在于我的问题更笼统(任何语言),而该问题特定于 Bash。这两个问题的答案基本相同。如果它与另一个站点上的问题太相似,请出于这个原因在这里关闭它。
在 terminfo(5) 中:
Variable String Capname TCapCode Description
---------------------------------------------------------------
cursor_up cuu1 up up one line
key_up kcuu1 ku up-arrow key
Run Code Online (Sandbox Code Playgroud)
我尝试使用 tput 并且它们产生相同的输出:
[STEP 102] # tput cuu1 | hd -C
00000000 1b 5b 41 |.[A|
00000003
[STEP 103] # tput kcuu1 | hd -C
00000000 1b 5b 41 |.[A|
00000003
[STEP 104] #
Run Code Online (Sandbox Code Playgroud)