1

我在所有其他节点上从集群中的主节点运行 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

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

4

1 回答 1

2

选项一:ssh提供 TTY

传递-tt给 ssh 以强制它提供 TTY,TERM如果您不相信 ssh 被配置为隐式执行,则显式传递:

#!/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 和系统实用程序自己使用全大写变量名称;只有小写名称才能保证其他应用程序可以安全使用)。

于 2017-08-10T16:53:25.277 回答