tput: нет значения для $TERM и не указано -T при запуске команды через ssh

Я запускаю сценарий оболочки с главного узла в кластере на всех других узлах, как

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

Но когда я запускаю его отдельно на каждом узле, он не выдает ошибки и печатает горизонтальную линию.


person lsbmsb    schedule 10.08.2017    source источник
comment
Но когда я запускаю его отдельно на каждом узле также как root?   -  person dbalakirev    schedule 10.08.2017
comment
Да как корень на каждом узле.   -  person lsbmsb    schedule 10.08.2017
comment
Вероятно, у вас есть TERM, когда вы работаете на узле.   -  person Charles Duffy    schedule 10.08.2017
comment
Установка COLUMNS вообще не имеет смысла, если нет терминала.   -  person Charles Duffy    schedule 10.08.2017


Ответы (1)


Вариант 1. Заставить ssh предоставить телетайп

Передайте -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 не является особенно четко определенным поведением; некоторые оболочки могут не разрешать это; они вполне соответствуют спецификации POSIX, поскольку утилиты оболочки и системные утилиты могут по-своему использовать все заглавные буквы. имена переменных; только имена в нижнем регистре гарантированно безопасны для использования другими приложениями).

person Charles Duffy    schedule 10.08.2017