як перевірити в bash, чи файл був створений більше x часу тому?


106

Я хочу перевірити в linux bash, чи створений файл більше x часу тому.

скажімо, файл називається text.txt, а час - 2 години.

 if [ what? ]
 then
     echo "old enough"
 fi

Відповіді:


138

Тільки на час модифікації

if test `find "text.txt" -mmin +120`
then
    echo old enough
fi

Ви можете використовувати -cminдля зміни або -aminдля доступу часу. Як зазначали інші, я не думаю, що ви можете відстежувати час створення.


3
ви можете кинути "тест" та підставки. Це аналогічно 'if (test == true)' vs 'if (test)'
гармати

2
Ви маєте рацію; Я думаю, я думав, що findповернувся не нульовим, коли не знайдено збігів.
гармати

4
Ви можете кинути задні посилання і робити, якщо тестувати $ (знайти text.txt -mmin +120)
tommy.carstensen

1
@BroSlow виглядайте краще: неможливо "більше одного". Звичайно, text.txtвважається , що це не каталог.
kmkaplan

2
Я віддаю перевагу цьому синтаксису:[ "$(find path/to/file -mmin +120)" ] && echo "it is old"
Alfe

42

Мені завжди подобалося використовувати, date -r /the/file +%sщоб знайти свій вік.

Ви також touch --date '2015-10-10 9:55' /tmp/fileможете отримати надзвичайно тонкий час у довільну дату / час.


Я сьогодні шукав те саме. Найкраще!
Умаїр А.

Дякую. Я приземлився на цьому питанні, тому що я гугл "як друкувати вік файлу". Тож саме це я шукав!
Ной Суссман

5
Дякую! Єдине застереження, що вищезазначене є часовою позначкою (не віком), але може бути використане для вирахування такого віку let AGE=$(($(date +%s)-$(date -r /path/to/file +%s))) [з припущенням, що створили і ніколи не змінювали, або "віком відносно моди"]
nhed 16.11.16

function file-age { FILE_CREATED_TIME=`date -r "$1" +%s`; TIME_NOW=`date +%s`; echo "$[ ${TIME_NOW} - ${FILE_CREATED_TIME} ]"; }
туріяг

1
@turiyag Обов'язкова примітка, що $[ ], якщо вона не застаріла , хоча б стара і менш портативна , і її слід використовувати $(( ))замість неї; і зворотні котирування більш крихкі, ніж $( ); а також дефіси в назвах функцій можуть бути не повністю портативними. Суть у цьому хороша, хоча!
michaelb958 - GoFundMonica

23

Використовуючи, statщоб визначити останню дату модифікації файлу, dateщоб визначити поточний час та ліберальне використання башизмів, можна зробити тест, який ви хочете, виходячи з часу останньої модифікації файлу 1 .

if [ "$(( $(date +"%s") - $(stat -c "%Y" $somefile) ))" -gt "7200" ]; then
   echo "$somefile is older then 2 hours"
fi

Хоча код трохи менш читабельний, ніж findпідхід, я думаю, що його кращий підхід, ніж запущений, findщоб переглянути файл, який ви вже "знайшли". Крім того, маніпуляції з побаченнями веселі ;-)


  1. Як Філ правильно зазначив, час створення не записується, але використовуйте %Zзамість %Yнижче, щоб отримати "час зміни", який може бути тим, що ви хочете.

[Оновлення]

Для користувачів Mac використовуйте stat -f "%m" $somefileзамість специфічного для синтаксису Linux вище


У яку оболонку вбудовані дата та статистика? Мій баш (GNU, 3.2.48) їх не має.
Ian Clelland

ой, вибач. statне вбудований - мене дуже погано, я виправлю.
Guss

1
Правильним рішенням @Guss є встановлення coretutils з варивом. :-)
Ерік Йоханссон

1
@ErikJohansson Я вважаю за краще не вимагати встановлення додаткового програмного забезпечення при використанні існуючого, добре працює - це не Windows, ви знаєте ;-)
Guss

1
Для людей, які хочуть використовувати це, але модифікувати його, було б добре знати, що він робить: $ (($ (дата + "% s") - секунди з 1970-01-01 00:00:00 UTC) (Epoch) $ (stat -c "% Y" $ somefile))) - час останньої модифікації як секунди з моменту епохи -gt "7200" - перевіряє, чи різниця більша за x кількість секунд.
devo

16

Час створення не зберігається.

Зберігаються три часові позначки (як правило, їх можна вимкнути в певних файлових системах або за допомогою певних опцій файлової системи):

  • Останній час доступу
  • Час останньої модифікації
  • Час останньої зміни

a "Зміна" у файлі зараховується як зміна дозволу, перейменування тощо. Поки модифікація є лише вмістом.


12

Хоча ctime технічно не час створення, він досить часто є.

Оскільки ctime на нього не впливають зміни вмісту файлу, він, як правило, оновлюється лише тоді, коли файл створений. І так - я чую, як ви всі кричали - він також оновлюється, якщо ви змінюєте дозволи доступу чи право власності ... але, як правило, це робиться один раз, як правило, в той же час, коли ви туди поміщаєте файл.

Особисто я завжди використовую mtime для всього, і я думаю, що саме цього ти хочеш. Але в будь-якому випадку ... ось перегляд "непривабливого" басса Гусса, у простій у використанні функції.

#! / бін / баш
функціональний вік () {
   локальне ім'я файлу = $ 1
   локальна змінена = `stat -c% Y" $ filename "`
   local now = `дата +% s`
   місцевий пройшов

   нехай минуло = тепер - змінено
   echo $ минуло
}

file = "/"
echo Вік $ файла становить $ (вік "$ файл") секунд.

Це було корисно, але це не спрацювало відразу для OSX, оскільки stat на ньому реалізований по-різному. Єдиним сумісним міжсистемним способом я знайшов використання perl. Сценарій повинен працювати на Macs, якщо замінити відповідний рядок цим: local changed=$(perl -MFile::stat -e "print stat(\"${filename}\")->mtime") superuser.com/questions/427551/…
Bijou Trouvaille,

1
"Час створення" - це поняття, яке важко зрозуміти. Що це означає для скопійованого файлу? Що для переміщеного файлу? Що робити, якщо його перемістили через межу пристрою (щоб він створився заново)? Що це означає для упакованого та пізніше нерозпакованого файлу? Тут можливі кілька відповідей, і єдиної думки не існує. Хоча згадування про час є приємним, але я б не ставив це семантично біля розпливчастої концепції "часу створення". Тим більше, що простий chmod, застосований до файлу, зведе нанівець цю ідею. Але я можу жити з вами, роблячи це ;-)
Алфе

@Alfe: Вам не вистачає +%sдругого тайму
Grizly

Цей вік може бути набагато коротшим: age() { echo $(( $(date +%s) - $(date -r "$1" +%s) )); } (Дякую @Grizly за виправлення!)
Алфе

Насправді краще використовувати час доступу, який є часом створення у всіх файлових системах, встановлених з noatimeопцією (що добре для продуктивності, тому ви повинні використовувати його). Тому просто використовуйте %Xзамість цього %Y.
Nux

7

Знайти це добре, але я думаю, що ви можете скористатися іншим способом, особливо якщо вам потрібно зараз, скільки секунд - це файл

date -d "now - $( stat -c "%Y" $filename ) seconds" +%s

з використанням дати GNU


використовувати gstat, "варити встановити coreutils"
Ерік Йоханссон,

3

Розглянемо результат інструменту "stat":

  File: `infolog.txt'
  Size: 694         Blocks: 8          IO Block: 4096   regular file
Device: 801h/2049d  Inode: 11635578    Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1000/     fdr)   Gid: ( 1000/     fdr)
Access: 2009-01-01 22:04:15.000000000 -0800
Modify: 2009-01-01 22:05:05.000000000 -0800
Change: 2009-01-01 22:05:05.000000000 -0800

Тут ви можете побачити три дати для доступу / зміни / зміни. Не створена дата. Ви можете бути впевнені лише в тому випадку, коли вміст файлу було змінено (поле "модифікувати") чи змінилося його вкладення (поле "змінити").

Приклади оновлення обох полів:

"Змінити" буде оновлено, якщо хтось об'єднав додаткову інформацію до кінця файлу.

"Змінити" буде оновлено, якщо хтось змінив дозволи через chmod.


надано, stat може повідомити вам відповідну інформацію. Але розібратися буде досить нудно, щоб отримати те, що ми хочемо.
PypeBros

0

я використовую

file_age() {
    local filename=$1
    echo $(( $(date +%s) - $(date -r $filename +%s) ))
}

is_stale() {
    local filename=$1
    local max_minutes=20
    [ $(file_age $filename) -gt $(( $max_minutes*60 )) ]
}

if is_stale /my/file; then
    ...
fi
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.