tput: "No value for $TERM and no -T specified" when command 运行 over ssh

tput: "No value for $TERM and no -T specified" when command run over ssh

我正在 运行ning shell 来自集群中所有其他节点上的主节点的脚本,

ssh root@"$node_name" 'bash -s' < ./script.sh

script.sh包含以下行,用于根据终端大小添加水平线的格式,

printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' -

它给出错误并且不打印水平线,

tput: No value for $TERM and no -T specified

但是当我在每个节点上单独 运行 它时,它不会给出错误并打印水平线。

选项一:让 ssh 提供 TTY

-tt 传递给 ssh 以强制它提供 TTY,如果您不信任 ssh 被配置为隐式这样做,则显式传递 TERM

#!/bin/bash
#      ^^^^- the below printf usage is not available in baseline POSIX sh

printf -v term_q '%q' "$TERM"
ssh -t root@"$node_name" "TERM=$term_q bash -s" < ./script.sh

当然,只有当您的 ssh 是来自终端的 运行 时,这才有意义。如果它是来自 cron 作业的 运行,那么您需要一些不同的东西。


方案二:凑合着用

您运行正在执行的操作仅在终端上下文中才有意义。没有终端,不存在终端宽度供tput查找;并且没有通过 TERM 环境变量设置终端类型,因此没有可用的控制序列。

考虑为非交互式使用设置默认值:

# if we have no TERM, and no preexisting COLUMNS, set our own
[[ $TERM || $COLUMNS ]] || COLUMNS=80

...或编写您的代码来处理案例本身:

# skip this command altogether if we have no TERM or COLUMNS
[[ $TERM || $COLUMNS ]] && printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' -

(请注意,分配给 COLUMNS 并不是特别明确的行为;某些 shell 可能不允许这样做;它们完全符合 POSIX 规范,因为允许 shell 和系统实用程序自己使用全部大写的变量名;只有小写的名称才能保证其他应用程序可以安全使用。