Используя команду sed в цикле for на нескольких серверах

ведущее тире '-' означает, что это файл.

ведущий 'd' означает каталог

ведущий 'l' означает ссылку на другой файл.

Первый символ определяет тип файла:

- : Обычный файл

b : Специальный файл блоков

c : Специальный файл символов

d : Каталог

l : Символьная ссылка

n : Сетевой файл

p : FIFO

s : Сокет

0
27.03.2019, 10:48
3 ответа

Попробуйте это,

for host in $(grep test /etc/hosts | cut -d' ' -f 1 | sort -u); do
    ssh $host 'sudo sed -i "s/enabled = 1/enabled = 0/" /etc/yum.repos.d/testing.repo'
done

мы должны заключать удаленные команды в кавычки.

2
28.01.2020, 02:18

Попробуйте изменить вот так

for host in $(cat /etc/hosts | grep text | cut -d' ' -f 1 | sort -u); do
   ssh $host \
   "sudo sed -i \"s/enabled = 1/enabled = 0/\" /etc/yum.repos.d/testing.repo"
done
1
28.01.2020, 02:18

Проблема в том, что команда, которая должна быть выполнена на удаленном узле, зависит от правильности обработки кавычек. Кавычки необходимо оценивать как часть команды на удаленной стороне, а не на локальном хосте. Это означает, что команде нужен дополнительный уровень кавычек.

Так как ваша текущая попытка неправильно заключает команду в кавычки, она разбита на пробелы на удаленном хосте. После этого команда sedстановится эквивалентом локальной команды

.
sed -i s/enabled = 1/enabled = 0/ /etc/yum.repos.d/testing.repo

, который, как говорится в сообщении об ошибке, содержит команду s, которая не завершена должным образом.

Кроме того, зацикливание подстановки команд неэстетично и опасно. Значение, до которого расширяется подстановка, будет разбито на слова по пробелам, а слова затем будут подвергнуты генерации имени файла (подстановке ). Это также требует, чтобы подстановка команд была полностью расширена, прежде чем цикл сможет даже начать свою первую итерацию.

Вместо этого используйте цикл read:

awk '/text/ && !seen[$1]++ { print $1 }' |
while IFS= read -r remote; do
    ssh -n "$remote" \
        'sudo sed -i "s/enabled = 1/enabled = 0/" /etc/yum.repos.d/testing.repo'
done

Обратите внимание на ssh -nздесь. Он останавливает sshот чтения своего стандартного входного потока, который в противном случае заставил бы его читать хосты, которые выводит команда awk. Кроме того, любое расширение переменной должно заключаться в двойные кавычки (, если вы не знаете, в каких контекстах это не требуется ).

Другим способом решения этой проблемы, очевидно, было бы вместо редактирования существующего файла на различных удаленных хостах отправить новую копию файла на каждую машину (, возможно, используя scpилиrsync). Однако для этого потребуется, чтобы файл выглядел одинаково на каждом хосте.

1
28.01.2020, 02:18

Теги

Похожие вопросы