LINUX.ORG.RU

Простой вопрос по bash для знающих

 ,


0

1

Нужно действующему скрипту добавить несколько функций. Сам скрипт умеет бесконечно писать в файл определенный цикл слов, то что мне и надо, но нехватает ограничение файла по весу его автоматическое сжатие и создание нового файла для следующего цикла с тем же набором слов а также его удаление после его сжатия. Типа, записал, сжал, создал новый а тот что сжал удалил, это все должно быть на автомате, что бы я не заморачивался в ручную.

Скрипт вызывается командой в командной строке так: ./script.sh

Сам скрипт:

#!/bin/bash

bash ‘/home/start/sh/file1.sh’ &
bash ‘/home/start/sh/file2.sh’ &
bash ‘/home/start/sh/file3.sh’ &

exit

Скрипт записи уже в файл, file1.sh

#!/bin/bash

TIMEOUT=0.1

 while true; do

    echo “Набор слов” >> /home/start/zip/file1

sleep 0.1
done




Последнее исправление: zte (всего исправлений: 3)

Я прочитал три раза, но так и не нашёл вопроса. Что сделать-то надо, конкретно? Что именно вызывает затруднения?

Если нужно, чтобы это «набор слов» писалось не бесконечно, а 1000 раз (это же и есть ограничение по объйму в результате), то используй for i in $(seq 1000) вместо while. Ну или проверяй объём файла в конце каждой итерации, то есть после echo, и выходи из цикла.

В общем, я нифига не понял, но если надо несколько файлов с этим самым «набор слов» несколько раз, то что-то типа:

#!/bin/sh

TIMEOUT=0.1
NUMBER_OF_FILES=100
TIMES_TO_WRITE_THE_PHRASE=1000

for filenumber in $(seq $NUMBER_OF_FILES); do
  for i in $(seq $TIMES_TO_WRITE_THE_PHRASE); do
    echo “Набор слов” >> /home/start/zip/file$filenumber
    sleep $TIMEOUT
  done
  zstd --или-чем-ты-там-жмёшь /home/start/zip/file$filenumber
done
CrX ★★★★★
()
Последнее исправление: CrX (всего исправлений: 3)
Ответ на: комментарий от zte
  1. Это не ответ на мой вопрос. Это какой-то фрагмент полёта мысли, подразумевающий, что мы должны понимать, что значит «типа записал» заранее. Ты знаешь, мы — нет.
  2. Ну строчку с rm после zstd добавь. То получается, что нужно, или нет?

В общем виде, если нужны файлы по номерам

#!/bin/sh

NUMBER_OF_FILES=100

# Это функция, которая делает «типа, записал»
tipa_write() {
    echo "Набор слов" > "$1"
    # тут добавь логику своего «типа, записал»
}

# Это цикл, который делает «записал, сжал, удалил для $NUMBER_OF_FILES файлов
# с именами по номерам (в примере — от 1 до 100)
for filenum in $(seq $NUMBER_OF_FILES); do
    # пишем
    tipa_write "$HOME/zip/filanems$filenum"
    # жмём
    zstd "$HOME/zip/filanems$filenum"
    # удаляем непожатое
    rm "$HOME/zip/filanems$filenum"
# И переходим к следующему файлу
done

P.S. у zstd есть опция --rm, которая позволяет удалять исходник сразу. В приведённом выше примере rm вызывается явно для наглядности, ибо это пример

CrX ★★★★★
()
Последнее исправление: CrX (всего исправлений: 2)
Ответ на: комментарий от zte
#!/bin/sh

MAX_FILESIZE=1024  # 1024 байта = 1 КБ
NUMBER_OF_FILES=100

# Это функция, которая делает «типа, записал»
tipa_write() {
    touch $1
    while [ "$(wc -c < $1 )" -lt $MAX_FILESIZE ]; do
        echo "Набор слов" >> $1
        # тут логика твоего типазаписала
    done
}

# Это цикл, который делает «записал, сжал, удалил для $NUMBER_OF_FILES файлов
# с именами по номерам (в примере — от 1 до 100)
for filenum in $(seq $NUMBER_OF_FILES); do
    # пишем
    tipa_write "$HOME/zip/filanems$filenum"
    # жмём
    zstd "$HOME/zip/filanems$filenum"
    # удаляем непожатое
    rm "$HOME/zip/filanems$filenum"
# И переходим к следующему файлу
done
CrX ★★★★★
()
Ответ на: комментарий от zte

Надо было изначально так задачу ставить.

Но вообще тебе походу правда logrotate надо.

Если нет, то предлагаю просто записывать последнее имя файла куда-то, а потом с него продолжать. Ну типа echo $filenum > lastfilenum.txt в начале каждой итерации. А при старте скрипта читать его, типа CURRENTFILENUM=$(cat lastfilenum.txt). Ну и значения в seq соответственно переписать.

CrX ★★★★★
()

Не уверен что понял нюансов задачи, и вот вообе не понял какого рода генератор «набора слов» (а всё это важно для правильной организации скрипта), но мне кажется задачу надо реорганизовать и вообще грамотно спроектировать. Чтобы свести к простой схеме простых последовательностей действий, чтобы проще было обернуть всё это в баш-скрипты.

Например есть некая команда, которая при однократном выполнении даёт кусочек этого самого набора слов. Допстим результат достигается при условно бесконечном её повторении с записью в условно бесконечный файл. Тогда...

...надо просто обернуть её в цикл и крутить его. Но т.к. число повторений и файл только условно бесконечны, то проворачивать по N раз, сразу писать эти N циклов в сжатый файл, а затем переходить к следующему файлу. Т.е. не пытаться оперировать понятием «размер файла», а только числом циклов.

А организуется это соответственно двойной-тройной вложенностью циклов ну и выносом «генератора 1 куска набора слов» в отдельный скрипт, так его проще вызвать из цикла. Всё разумеется зависит от нюансов задачи. Ну и всё можно вывернуть наизнанку если требуется распаралелить.

У меня есть мои скрипто-наработки по похожим задачам, в т.ч. с паралельностью и конвеерной обработкой появляющихся и исчезающих файлов. Могу навалить сюда в качестве примеров, если есть желание повтыкать в чужой код. Иначе нужны конкретные вопросы по тем самым нюансам.

kirill_rrr ★★★★★
()

Тебе правильно советуют logrotate, он простой как мычание.

Создаёшь файл /home/start/zip/mylogrotate.conf вот такой

/home/start/zip/file1 {
        size 1k
        rotate 99
        compress
}

После каждого запуска твоего скрипта вызываешь команду

# "--state" это нужно, чтобы запускать logrotate от пользователя, хотя обычно это системный сервис, запускаемый каждый день ночью
logrotate --state /home/start/zip/mylogrotate.state /home/start/zip/mylogrotate.conf

Если файл больше 1кб, то он будет сжат и переименован в file1.1.gz, а существующие будут переименованы в .2.gz .3.gz и т.д. до самого старого .99.gz, который будет удалён.

legolegs ★★★★★
()
Ответ на: комментарий от legolegs

сжимает так не хило >>bzip2 $HOME/go/bzip2/filanems$filenum просто файл при обрыве не дописывается а переписывается, это в лучшем случае.

в простом примере, без сжатий, это делается двумя скобами всего навсего >>

 #!/bin/bash

TIMEOUT=0.1

while true; do

echo «набор слов» >> /home/start/file

sleep 0.1 done 

zte
() автор топика
Ответ на: комментарий от CrX

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

for filenum in $(seq $NUMBER_OF_FILES); do
    # пишем
    tipa_write "$HOME/zip/`date +%x-%N`-$filenum"
    # жмём
    bzip2 "$HOME/zip/`date +%x*`-$filenum"
    # удаляем непожатое
    rm -f "$HOME/zip/`date +%x*`-$filenum"
# И переходим к следующему файлу
done

но bzip2 не всегда подхватывает такую строку или вообще не подхватывает

    bzip2 "$HOME/zip/`date +%x*`-$filenum"

может есть альтернатива звездочке +%x*

zte
() автор топика
Последнее исправление: zte (всего исправлений: 1)
Ответ на: комментарий от CrX

Разобрался, еще бы научить этот скрипт на лету сжимать файлы.

for filenum in $(seq $NUMBER_OF_FILES); do
    date=`date +%x-%N`
    # пишем
    tipa_write "$HOME/zip/$date-$filenum"
    # жмём
    bzip2 "$HOME/zip/$date-$filenum"
    # удаляем непожатое
    rm -f "$HOME/zip/$date-$filenum"
# И переходим к следующему файлу
done

zte
() автор топика
Ответ на: комментарий от zte

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

CrX ★★★★★
()
Последнее исправление: CrX (всего исправлений: 1)