При переносе вам придется использовать 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
.
Вы не можете просто так перенаправить стандартный ввод сеанса ssh. Вы должны увидеть сообщение об ошибке что-то вроде:
Псевдотерминал -не будет выделен, поскольку стандартный ввод не является терминалом
Вам нужно использовать опцию -tt для ssh, чтобы принудительно выделить псевдотерминал. Попробуйте это:
#!/bin/bash
for i in `cat list`
echo $server
echo "------------------------------------------"
ssh -tt $server << MYCOMMANDS
cd /tmp
rm log52.log
MYCOMMANDS
#! /bin/bash
for i in `cat list`
do
echo $i
echo "-------------------------"
ssh $i "rm /tmp/log52.log"
done
Если вам нужно удалить только один файл, вы можете просто указать это в одной строке. Кроме того, может оказаться полезным добавить -f
к rm
.
Единственная реальная проблема с вашим кодом заключается в том, что в вашем цикле отсутствуют 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
файлу ). Без -n
ssh
будет считывать оставшееся содержимое 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
команд одновременно ).