ฉันจะตรวจสอบใน bash ได้อย่างไรว่าไฟล์ถูกสร้างขึ้นนานกว่า x ครั้งก่อนหรือไม่


106

ฉันต้องการตรวจสอบใน linux bash ว่ามีการสร้างไฟล์เกิน x ครั้งที่แล้วหรือไม่

สมมติว่าไฟล์นี้เรียกว่า text.txt และเวลาคือ 2 ชั่วโมง

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

คำตอบ:


139

สำหรับเวลาปรับเปลี่ยนเท่านั้น

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

คุณสามารถใช้-cminสำหรับการเปลี่ยนแปลงหรือ-aminเวลาเข้าถึง อย่างที่คนอื่นชี้ฉันไม่คิดว่าคุณจะติดตามเวลาสร้างได้


3
คุณสามารถวาง 'การทดสอบ' และการย้อนกลับได้ สิ่งนี้คล้ายคลึงกับ 'if (test == true)' vs 'if (test)'
ปืน

2
คุณถูกต้อง; ฉันคิดว่าฉันคิดว่าการfindส่งคืนไม่ใช่ศูนย์เมื่อไม่พบรายการที่ตรงกัน
ปืน

4
คุณสามารถวาง backticks และทำถ้าทดสอบ $ (ค้นหา 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เพื่อให้ได้เวลาที่ละเอียดมากในวัน / เวลาโดยพลการ


ฉันมองหาสิ่งเดียวกันในวันนี้ ดีที่สุด!
Umair A.

ขอบคุณ. ฉันพบคำถาม SO นี้เพราะฉัน googled "วิธีพิมพ์อายุของไฟล์ทุบตี" นี่คือสิ่งที่ฉันกำลังมองหา!
Noah Sussman

5
ขอบคุณ! โดยมีข้อแม้เพียงข้อเดียวว่าข้างต้นเป็นเวลาบันทึก (ไม่ใช่อายุ) แต่สามารถใช้เพื่อคำนวณอายุได้เช่นนั้น let AGE=$(($(date +%s)-$(date -r /path/to/file +%s))) [ด้วยสมมติฐานที่สร้างขึ้นและไม่เคยแก้ไขหรือ "อายุสัมพันธ์กับ mod"]
เมื่อ

function file-age { FILE_CREATED_TIME=`date -r "$1" +%s`; TIME_NOW=`date +%s`; echo "$[ ${TIME_NOW} - ${FILE_CREATED_TIME} ]"; }
turiyag

1
@turiyag หมายเหตุบังคับนั่น$[ ]คือถ้าไม่เลิกใช้งานอย่างน้อยก็เก่าและพกพาได้น้อยกว่าและควรใช้$(( ))แทน และ backquotes เปราะบางกว่า$( ); และขีดกลางในชื่อฟังก์ชันอาจไม่สามารถพกพาได้อย่างสมบูรณ์ แก่นของมันดี แต่!
michaelb958 - GoFundMonica

24

การใช้statที่จะคิดออกวันที่แก้ไขล่าสุดของไฟล์dateที่จะคิดออกเวลาปัจจุบันและนิยมใช้ bashisms หนึ่งสามารถทำแบบทดสอบที่คุณต้องการขึ้นอยู่กับเวลาการปรับเปลี่ยนไฟล์สุดท้าย1

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

แม้ว่าโค้ดจะอ่านได้น้อยกว่าfindวิธีนี้ แต่ฉันคิดว่ามันเป็นแนวทางที่ดีกว่าจากนั้นก็วิ่งfindไปดูไฟล์ที่คุณ "พบ" แล้ว นอกจากนี้การจัดการวันที่เป็นเรื่องสนุก ;-)


  1. เนื่องจาก Phil ระบุเวลาในการสร้างอย่างถูกต้องจะไม่ถูกบันทึก แต่ใช้%Zแทน%Yด้านล่างเพื่อรับ "เวลาเปลี่ยน" ซึ่งอาจเป็นสิ่งที่คุณต้องการ

[อัปเดต]

สำหรับผู้ใช้ mac ให้ใช้stat -f "%m" $somefileแทนไวยากรณ์เฉพาะของ Linux ด้านบน


วันที่และสถิติที่สร้างขึ้นในเชลล์คืออะไร? Bash ของฉัน (GNU, 3.2.48) ไม่มี
Ian Clelland

โอ๊ะขอโทษ statไม่ได้อยู่ในตัว - ฉันแย่มากฉันจะแก้ไข
Guss

1
@Guss ทางออกที่ถูกต้องคือการติดตั้ง coretutils ด้วยการชง :-)
Erik Johansson

1
@ErikJohansson ฉันไม่ต้องการติดตั้งซอฟต์แวร์เพิ่มเติมเมื่อใช้ซอฟต์แวร์ที่มีอยู่ทำงานได้ดี - นี่ไม่ใช่ Windows คุณก็รู้ ;-)
Guss

1
สำหรับผู้ที่ต้องการใช้สิ่งนี้ แต่แก้ไขมันจะเป็นการดีที่จะรู้ว่ามันกำลังทำอะไร: $ (($ (date + "% s") - วินาทีตั้งแต่ 1970-01-01 00:00:00 UTC (Epoch) $ (stat -c "% Y" $ somefile))) - เวลาของการแก้ไขครั้งล่าสุดเป็นวินาทีนับตั้งแต่ Epoch -gt "7200" - ตรวจสอบว่าความแตกต่างมากกว่า x จำนวนวินาทีหรือไม่
devo

16

ไม่ได้จัดเก็บเวลาสร้าง

สิ่งที่จัดเก็บคือการประทับเวลาสามแบบ (โดยทั่วไปสามารถปิดได้ในระบบไฟล์บางระบบหรือโดยตัวเลือกระบบไฟล์บางอย่าง):

  • เวลาเข้าถึงล่าสุด
  • เวลาแก้ไขล่าสุด
  • เวลาเปลี่ยนแปลงล่าสุด

"เปลี่ยน" ไฟล์จะนับเป็นการเปลี่ยนแปลงสิทธิ์เปลี่ยนชื่อ ฯลฯ ในขณะที่การแก้ไขเป็นเนื้อหาเท่านั้น


12

แม้ว่า ctime จะไม่ใช่ช่วงเวลาแห่งการสร้างในทางเทคนิคแต่ก็มักจะเป็นเช่นนั้น

เนื่องจาก ctime จะไม่ได้รับผลกระทบจากการเปลี่ยนแปลงเนื้อหาของไฟล์จึงมักจะอัปเดตเมื่อไฟล์ถูกสร้างขึ้นเท่านั้น และใช่ - ฉันได้ยินคุณทุกคนกรีดร้อง - นอกจากนี้ยังอัปเดตหากคุณเปลี่ยนสิทธิ์การเข้าถึงหรือการเป็นเจ้าของ ... แต่โดยทั่วไปแล้วจะเป็นสิ่งที่ทำครั้งเดียวโดยปกติแล้วคุณจะวางไฟล์ไว้ที่นั่นในเวลาเดียวกัน

โดยส่วนตัวแล้วฉันมักจะใช้ mtime สำหรับทุกสิ่งและฉันคิดว่านั่นคือสิ่งที่คุณต้องการ แต่อย่างไรก็ตาม ... นี่คือการปรับปรุงการทุบตีที่ "ไม่น่าสนใจ" ของ Guss ในฟังก์ชันที่ใช้งานง่าย

#! / bin / ทุบตี
อายุการใช้งาน () {
   ชื่อไฟล์ในเครื่อง = $ 1
   เปลี่ยนในเครื่อง = `stat -c% Y" $ filename "`
   local now = `date +% s`
   ท้องถิ่นผ่านไป

   let elapsed = now-change
   echo $ ผ่านไปแล้ว
}

ไฟล์ = "/"
echo อายุของ $ file คือ $ (age "$ file") วินาที

สิ่งนี้มีประโยชน์ แต่ใช้งานไม่ได้ในทันทีสำหรับ OSX เนื่องจากสถิติถูกนำไปใช้ต่างกัน วิธีเดียวที่เข้ากันได้ข้ามระบบที่ฉันพบคือใช้ perl สคริปต์ควรทำงานบน Macs หากคุณแทนที่บรรทัดที่เกี่ยวข้องด้วยสิ่งนี้: local changed=$(perl -MFile::stat -e "print stat(\"${filename}\")->mtime") superuser.com/questions/427551/…
Bijou Trouvaille

1
"เวลาสร้าง" เป็นแนวคิดที่เข้าใจยาก ไฟล์ที่คัดลอกหมายถึงอะไร? ไฟล์ที่ถูกย้ายคืออะไร? จะเกิดอะไรขึ้นถ้ามันถูกย้ายข้ามพรมแดนอุปกรณ์ (ดังนั้นมันจึงถูกสร้างขึ้นใหม่ในแง่หนึ่ง)? หมายความว่าอย่างไรสำหรับไฟล์ที่แยกแพ็กเกจและไฟล์ในภายหลัง เป็นไปได้หลายคำตอบที่นี่และไม่มีฉันทามติ แม้ว่าการพูดถึง ctime นั้นดี แต่ฉันจะไม่ใส่ความหมายใกล้กับแนวคิดที่คลุมเครือของ "เวลาสร้าง" โดยเฉพาะอย่างยิ่งเมื่อchmodใช้กับไฟล์อย่างง่ายจะทำให้ความคิดนั้นเป็นโมฆะ แต่ฉันสามารถอยู่กับคุณได้ ;-)
Alfe

@Alfe: คุณพลาด+%sจากครึ่งหลัง
Grizly

อายุนั้นอาจสั้นลง: age() { echo $(( $(date +%s) - $(date -r "$1" +%s) )); } (ขอบคุณ @Grizly สำหรับการแก้ไข!)
Alfe

จริงๆแล้วควรใช้เวลาในการเข้าถึงซึ่งเป็นเวลาในการสร้างบนระบบไฟล์ทั้งหมดที่ติดตั้งด้วยnoatimeตัวเลือก (ซึ่งดีต่อประสิทธิภาพดังนั้นคุณควรใช้) ดังนั้นให้ใช้%Xแทน%Y.
Nux

7

การค้นหานั้นดี แต่ฉันคิดว่าคุณสามารถใช้ anotherway ได้โดยเฉพาะอย่างยิ่งถ้าคุณต้องการตอนนี้ไฟล์เก่ากี่วินาที

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

ใช้วันที่ GNU


ใช้ gstat, "brew install coreutils"
Erik Johansson

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

คุณสามารถดูวันที่สามวันสำหรับการเข้าถึง / แก้ไข / เปลี่ยนแปลงได้ที่นี่ ไม่มีวันที่สร้าง คุณจะมั่นใจได้ก็ต่อเมื่อมีการแก้ไขเนื้อหาของไฟล์ (ช่อง "แก้ไข") หรือมีการเปลี่ยนแปลง inode (ช่อง "เปลี่ยน")

ตัวอย่างเมื่อทั้งสองฟิลด์ได้รับการอัปเดต:

"ปรับเปลี่ยน" จะได้รับการอัปเดตหากมีคนต่อข้อมูลเพิ่มเติมที่ส่วนท้ายของไฟล์

"เปลี่ยนแปลง" จะได้รับการอัปเดตหากมีผู้เปลี่ยนสิทธิ์ผ่าน chmod


ได้รับสถิติสามารถบอกข้อมูลที่เกี่ยวข้องกับคุณได้ แต่จะค่อนข้างน่าเบื่อในการแยกวิเคราะห์เพื่อให้ได้สิ่งที่เราต้องการ
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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.