Reputation: 39
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
Reputation: 295291
ssh
provide a TTYPass -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.
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