lsbmsb
lsbmsb

Reputation: 39

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

I am running shell script from master node in the cluster on all other nodes as,

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

script.sh contains the following line which is used for formatting which adds horizontal line according to the size of the terminal,

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

Which gives error and does not print the horizontal line,

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

But when I run it individually on each node, it does not give an error and prints horizontal line.

Upvotes: 1

Views: 4397

Answers (1)

Charles Duffy
Charles Duffy

Reputation: 295291

Option One: Making ssh provide a TTY

Pass -tt to ssh to force it to provide a TTY, and pass TERM through explicitly if you don't trust ssh to be configured to do so implicitly:

#!/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

Of course, this only makes sense if your ssh is run from a terminal. If it's run from a cron job, then you need something different.


Option Two: Making Do Without One

The operation you're running is one that only makes sense in the context of a terminal. With no terminal, there doesn't exist a terminal width for tput to look up; and with no terminal type set via the TERM environment variable, there's no control sequence available for it to use.

Consider setting a default for noninteractive use:

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

...or writing your code to handle the case itself:

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

(Note that assigning to COLUMNS is not particularly well-defined behavior; some shells may not allow it; they're well within the POSIX specification to do so, as the shell and system utilities are allowed to make their own use of all-caps variable names; only lower-case names are guaranteed safe for other applications to use).

Upvotes: 2

Related Questions