2012-08-10 7 views
11

मैं 'कैशमे' कमांड के कार्यान्वयन की तलाश में हूं, जो '' एआरजीवी में जो कुछ भी है, उसका आउटपुट करता है। यदि यह कभी नहीं चला, तो यह इसे चलाएगा और कुछ हद तक आउटपुट को याद रखेगा। यदि यह इसे चलाता है, तो यह फ़ाइल के आउटपुट की प्रतिलिपि बनायेगा (या इससे भी बेहतर, आउटपुट और त्रुटि दोनों क्रमशः & 1 और & 2)।क्या मैं सीएलआई से लिनक्स पर कमांड के आउटपुट को कैश कर सकता हूं?

मान लें कि किसी ने यह आदेश लिखा है, यह इस तरह काम करेगा।

$ time cacheme sleep 1 # first time it takes one sec 
real 0m1.228s 
user 0m0.140s 
sys 0m0.040s 

$ time cacheme sleep 1 # second time it looks for stdout in the cache (dflt expires in 1h) 
#DEBUG# Cache version found! (1 minute old) 

real 0m0.100s 
user 0m0.100s 
sys 0m0.040s 

यह उदाहरण थोड़ा मूर्ख है क्योंकि इसमें कोई आउटपुट नहीं है। आदर्श रूप से यह नींद -1-and-echo-hello-world.sh जैसी स्क्रिप्ट पर परीक्षण किया जाएगा।

मैंने एक छोटी सी स्क्रिप्ट बनाई है जो पूर्ण कमांड नाम और उपयोगकर्ता नाम के हैश के साथ/tmp/में फ़ाइल बनाता है, लेकिन मुझे पूरा यकीन है कि कुछ पहले से मौजूद है।

क्या आप इनमें से किसी के बारे में जानते हैं?

+0

उपयोग का मामला क्या है? आप यह क्यों चाहते हैं? –

+1

उदाहरण के लिए, एक स्क्रिप्ट जो निष्पादित करने में आयु लेती है लेकिन सामान्य रूप से लगातार आउटपुट देती है, जिन मामलों में आप एक नया जवाब रखने में रुचि नहीं रखते हैं, लेकिन सिर्फ एक अच्छा पुराना संस्करण नहीं है। – Riccardo

+1

यह 'मेक' –

उत्तर

1

वैकल्पिक तर्क के रूप में समाप्ति आयु को जोड़कर कुछ हद तक बेहतर समाधान।

#!/bin/sh 
# save as e.g. $HOME/.local/bin/cacheme 
# and then chmod u+x $HOME/.local/bin/cacheme 
VERBOSE=false 
PROG="$(basename $0)" 
DIR="${HOME}/.cache/${PROG}" 
mkdir -p "${DIR}" 
EXPIRY=600 # default to 10 minutes 
# check if first argument is a number, if so use it as expiration (seconds) 
[ "$1" -eq "$1" ] 2>/dev/null && EXPIRY=$1 && shift 
[ "$VERBOSE" = true ] && echo "Using expiration $EXPIRY seconds" 
CMD="[email protected]" 
HASH=$(echo "$CMD" | md5sum | awk '{print $1}') 
CACHE="$DIR/$HASH" 
test -f "${CACHE}" && [ $(expr $(date +%s) - $(date -r "$CACHE" +%s)) -le $EXPIRY ] || eval "$CMD" > "${CACHE}" 
cat "${CACHE}" 
+0

1. शायद एक उपयोग अच्छा होगा: "yourscript.sh नींद 1" काम नहीं करता है। 2।मुझे लाइन 6 समझ में नहीं आता है: ["$ 1" -eq "$ 1"] क्या है? – Riccardo

+0

दस्तावेज़ीकरण के लिए कुछ टिप्पणियां जोड़ा गया। "$ 1" -eq "$ 1" सामान यह पता लगाने के लिए जादू है कि क्या पहला तर्क अगर एक पूर्णांक - यदि ऐसा है - तो सेकंड में समाप्ति समय सेट करने के लिए इसका उपयोग करें। इसे "yourscript.sh नींद 1" में तर्क के साथ काम करने के लिए भी eval जोड़ा गया। – error

+2

यह बात बहुत अच्छी है, क्या किसी ने इसका उचित उपयोग किया है? वांछित विशेषताओं, दस्तावेज़, कचरा संग्रह (वर्तमान में समाप्त होने वाली कैश आइटम केवल ओवरराइट होने पर ही हटा दिए जाते हैं), विभिन्न झंडे, (केवल कैश का उपयोग करें, कैशिंग सीडर, कैशिंग निकास कोड), और कुछ POSIX स्क्रिप्ट अनुकूलन। – agc

1

समाधान मैं रूबी में आया था यह है। क्या कोई भी अनुकूलन देखता है?

#!/usr/bin/env ruby 

VER = '1.2' 
$time_cache_secs = 3600 
$cache_dir = File.expand_path("~/.cacheme") 

require 'rubygems' 
begin 
    require 'filecache'   # gem install ruby-cache 
rescue Exception => e 
    puts 'gem filecache requires installation, sorry. trying to install myself' 
    system 'sudo gem install -r filecache' 
    puts 'Try re-running the program now.' 
    exit 1 
end 

=begin 
    # create a new cache called "my-cache", rooted in /home/simon/caches 
    # with an expiry time of 30 seconds, and a file hierarchy three 
    # directories deep 
=end 
def main 
    cache = FileCache.new("cache3", $cache_dir, $time_cache_secs, 3) 
    cmd = ARGV.join(' ').to_s # caching on full command, note that quotes are stripped 
    cmd = 'echo give me an argment' if cmd.length < 1 

    # caches the command and retrieves it 
    if cache.get('output' + cmd) 
    #deb "Cache found!(for '#{cmd}')" 
    else 
    #deb "Cache not found! Recalculating and setting for the future" 
    cache.set('output' + cmd, `#{cmd}`) 
    end 
    #deb 'anyway calling the cache now' 
    print(cache.get('output' + cmd)) 
end 

main 
2

इस सरल खोल स्क्रिप्ट (परीक्षण नहीं किया गया) के बारे में कैसे?

#!/bin/sh 

mkdir -p cache 

cachefile=cache/cache 

for i in "[email protected]" 
do 
    cachefile=${cachefile}_$(printf %s "$i" | sed 's/./\\&/g') 
done 

test -f "$cachefile" || "[email protected]" > "$cachefile" 
cat "$cachefile" 
+0

यह काम नहीं करता है :( कैश: रेखा 13: अनपेक्षित ईओएफ मिलान करने के लिए '0 'कैश: लाइन 14: वाक्यविन्यास त्रुटि: फ़ाइल का अप्रत्याशित अंत – Riccardo

+1

स्पष्ट गलती (पंक्ति 12 में बंद' 'को सही किया जाना चाहिए) चाहिए। अब काम करें। –

1

मैंने बैश के लिए एक सरल कैशिंग स्क्रिप्ट लागू की है, क्योंकि मैं speed up plotting from piped shell command in gnuplot चाहता था। इसका उपयोग किसी भी कमांड के आउटपुट को कैश करने के लिए किया जा सकता है। जब तक तर्क समान होते हैं तब तक कैश का उपयोग किया जाता है और तर्कों में पारित फाइलें नहीं बदली जाती हैं। प्रणाली सफाई के लिए जिम्मेदार है।

#!/bin/bash 

# hash all arguments 
KEY="[email protected]" 

# hash last modified dates of any files 
for arg in "[email protected]" 
do 
    if [ -f $arg ] 
    then 
    KEY+=`date -r "$arg" +\ %s` 
    fi 
done 

# use the hash as a name for temporary file 
FILE="/tmp/command_cache.`echo -n "$KEY" | md5sum | cut -c -10`" 

# use cached file or execute the command and cache it 
if [ -f $FILE ] 
then 
    cat $FILE 
else 
    [email protected] | tee $FILE 
fi 

आप स्क्रिप्ट cache, सेट निष्पादन झंडा नाम रख कर अपनी PATH में रख सकते हैं। फिर इसे उपयोग करने के लिए cache के साथ किसी भी कमांड को उपसर्ग करें।

0

एक कार्यान्वयन यहां मौजूद है: https://bitbucket.org/sivann/runcached/src कैश निष्पादन योग्य पथ, आउटपुट, निकास कोड, तर्क याद करता है। विन्यास योग्य समाप्ति। बैश, सी, पायथन में कार्यान्वित, जो कुछ भी आपको उपयुक्त बनाता है चुनें।

संबंधित मुद्दे

 संबंधित मुद्दे