slumtrimpet
slumtrimpet

Reputation: 3267

Unique Linux filename, sortable by time

Previously I was using uuidgen to create unique filenames that I then need to iterate over by date/time via a bash script. I've since found that simply looping over said files via 'ls -l' will not suffice because evidently I can only trust the OS to keep timestamp resolution in seconds (nonoseconds is all zero when viewing files via stat on this particular filesystem and kernel)

So I then though maybe I could just use something like date +%s%N for my filename. This will print the seconds since 1970 followed by the current nanoseconds.

I'm possibly over-engineering this at this point, but these are files generated on high-usage enterprise systems so I don't really want to simply trust the nanosecond timestamp on the (admittedly very small) chance two files are generated in the same nanosecond and we get a collision.

I believe the uuidgen script has logic baked in to handle this occurrence so it's still guaranteed to be unique in that case (correct me if I'm wrong there... I read that someplace I think but the googles are failing me right now).

So... I'm considering something like

FILENAME=`date +%s`-`uuidgen -t`
echo $FILENAME

to ensure I create a unique filename that can then be iterated over with a simple 'ls' and who's name can be trusted to both be unique and sequential by time.

Any better ideas or flaws with this direction?

Upvotes: 4

Views: 4175

Answers (3)

lurker
lurker

Reputation: 58284

If you order your date format by year, month (zero padded), day (zero padded), hour (zero padded), minute (zero padded), then you can sort by time easily:

FILENAME=`date '+%Y-%m-%d-%H-%M'`-`uuidgen -t`
echo $FILENAME

or

FILENAME=`date '+%Y-%m-%d-%H-%M'`-`uuidgen -t | head -c 5`
echo $FILENAME

Which would give you:

2015-02-23-08-37-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

or

2015-02-23-08-37-xxxxx
# the same as above, but shorter unique string

You can choose other delimiters for the date/time besides - as you wish, as long as they're within the valid characters for Linux file name.

Upvotes: 7

candymanuu
candymanuu

Reputation: 110

You could take what TIAGO said about %N precision, and combine it with taskset You can find some info here: http://manpages.ubuntu.com/manpages/hardy/man1/taskset.1.html and then run your script

taskset --cpu-list 1 my_script

Never tested this, but, it should run your script only on the first core of your CPU. I'm thinking that if your script runs on your first CPU core, combined with date %N (nanoseconds) + uuidgen there's no way you can get duplicate filenames.

Upvotes: 1

Tiago Lopo
Tiago Lopo

Reputation: 7959

You will need %N for precision (nanoseconds):

filename=$(date +%s.%N)_$(uuidgen -t); echo $filename
1424699882.086602550_fb575f02-bb63-11e4-ac75-8ca982a9f0aa

BTW if you use %N and you're not using multiple threads, it should be unique enough.

Upvotes: 2

Related Questions