Удаленный запуск нескольких команд с помощью сценария bash

При переносе вам придется использовать perlдля сбора временных меток, вычитания необходимого количества времени, а затем форматировать его для touch.

t=$(perl make-oldest 1 dir/*)
if [ "$t" -gt 0 ]
then
  touch -t "$t" file
else
  echo "Sorry, unable to find a file!"
fi

... и самым старым perl-скриптом make -является:

#!/usr/bin/perl -w
use strict;
use POSIX qw(strftime);

my $subtract = shift;
my $oldest = 0;
for (@ARGV) {
  my @s = stat;
  next unless @s;
  if ($oldest) {
    $oldest = $s[9] if $s[9] < $oldest;
  } else {
    $oldest = $s[9];
  }
}

if ($oldest) {
  # convert ($oldest - $subtract) into CCCCYYMMDDhhmm.SS
  print strftime "%Y%m%d%H%M.%S\n", localtime($oldest - $subtract);
} else {
  print "0\n";
}

Цель состоит в том, чтобы ваша оболочка расширила подстановочный знак dir/*, чтобы получить список имен файлов. У perl-скрипта есть «два» аргумента :: количество секунд, которое нужно вычесть из самого старого файла, и список файлов, из которых нужно собрать временные метки.

Perl-скрипт получает аргумент вычитания, затем циклически перебирает заданные файлы и отслеживает время самой старой модификации. Если он не может прочитать какие-либо файлы, он вернет ноль (, как проверено скриптом-оболочкой выше ). Если был найден самый старый файл,затем мы используем функцию strftimeдля преобразования вычитаемой метки времени в соответствующий формат для touch.

0
27.05.2021, 22:10
3 ответа

Вы не можете просто так перенаправить стандартный ввод сеанса ssh. Вы должны увидеть сообщение об ошибке что-то вроде:

Псевдотерминал -не будет выделен, поскольку стандартный ввод не является терминалом

Вам нужно использовать опцию -tt для ssh, чтобы принудительно выделить псевдотерминал. Попробуйте это:

#!/bin/bash
for i in `cat list`
echo $server
echo "------------------------------------------"
ssh -tt $server << MYCOMMANDS
cd /tmp
rm log52.log
MYCOMMANDS
-2
28.07.2021, 11:28
#! /bin/bash
for i in `cat list`
do
    echo $i
    echo "-------------------------"
    ssh $i "rm /tmp/log52.log"
done

Если вам нужно удалить только один файл, вы можете просто указать это в одной строке. Кроме того, может оказаться полезным добавить -fк rm.

0
28.07.2021, 11:28

Единственная реальная проблема с вашим кодом заключается в том, что в вашем цикле отсутствуют doи done, что приведет к синтаксическим ошибкам, и что вы используете iв качестве переменной цикла, но пытаетесь соединиться с некоторыми serverпеременная, которая вполне может быть не установлена.

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

В большинстве случаев лучше читать ввод построчно, вот так:

while IFS= read -r remote; do
    ssh -n "$remote" 'rm -f /tmp/log52.log'
done <list

Я использую ssh -nздесь, чтобы остановить sshот чтения своего стандартного входного потока (, который будет подключен к listфайлу ). Без -nsshбудет считывать оставшееся содержимое list, и ваш цикл будет выполнять только одну итерацию.

В качестве альтернативы, если вы действительно хотите прочитать команды из здесь -документа:

while IFS= read -r remote; do
    ssh -T "$remote" <<'END'
rm -f /tmp/log52.log
END
done <list

Здесь я использую ssh -Tдля явного отключения выделения псевдо-терминалов -, что не требуется, поскольку мы не делаем ничего, что требует взаимодействия с пользователем. Я делаю это, потому что sshзаметит, что в его стандартном входном потоке есть данные, поэтому он предупредит нас о том, что в удаленной системе нет работающего терминала для интерактивных действий. Нам не нужны -nс sshздесь, так как мы переназначаем стандартный входной поток для sshиз документа здесь -.

Но цикл можно заменить одной командой

xargs -I {} ssh {} 'rm -f /tmp/log52.log' <list

... где утилита xargsпрочитает строк из файла list, заменит {}в команде sshстрокой, прочитанной из файла, и выполнит действие доступ к удаленным системам для удаления определенного файла. Я использую rm -f, чтобы не вызывать ошибку, если нет файла для удаления.

Некоторые реализации xargsдопускают параллельное выполнение утилиты, например.-P 4(будет поддерживать не более четырех параллельных sshкоманд одновременно ).

2
28.07.2021, 11:28

Теги

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