Bashで利用可能な組み込みキャッシュコマンドはありますか(mktempやSpongeなど)。

Bashで利用可能な組み込みキャッシュコマンドはありますか(mktempやSpongeなど)。

ec2-describe-instancesリクエストして出力を表示するのに2〜5秒かかりますので、少し痛みを伴うAmazon ec2コマンドラインツールを使用しています。

使用を検討しています。fec2din次のツールこの問題私は出力フォーマットを指定し、ec2-describe-instances呼び出し出力をキャッシュする最良の方法が何であるか疑問に思います。

fec2dinmktemp出力フォーマットを指定するために使用される一時ファイルを作成するために使用されますawk

ec2-describe-instancesキャッシュされたファイルのタイムスタンプが特定の時間より古い場合にのみ実行されるTTLパラメータで使用できるツールはありますか?

spongeこれを行うことができるユーティリティ(例:help)があればstdout良いでしょう。

答え1

この方法で問題を解決することはできませんが、次のことをお勧めします。Amazon EC2優れたボート代わりに、これAmazon Web Services インターフェイスを提供する Python パッケージ

ほぼすべて覆うAmazon EC2 API ツールしかし、現代的で高速なAWS REST APIを使用して痛みを伴う遅延を経験することはありません。EC2 APIツールどちらもJavaで書かれており、古くて遅いSOAP APIを使用することに慣れています(方向が変わったかどうかはわかりませんが、ユーザーの経験とまだ必要です)。AWS X.509 証明書別に提案するようです)。

また、これらの機能を使用する必要はありません。AWS X.509 証明書これ以上ではありませんが、今日のより一般的で柔軟な方法は次のように使用できます。AWS アクセスキー IDそしてAWS シークレットアクセスキーまた、次のように提供することができます(そして一般的に提供する必要があります)。AWS ID およびアクセス管理 (IAM)デフォルトのAWSアカウントの認証情報が公開されないようにしてください。

最も重要なことは、ボートPythonスクリプトを使用して日常的なAWSの使用を調整できる確かな候補です。もちろんそうすることも可能ですbashが、アイデアを得ることができます。

文書

ドキュメントと例は以下にあります。boto: Amazon Web Services への Python インターフェイス、これはまともな(つまり、やや完全な)を提供します。APIリファレンス(例えばEC2)だけでなく、複数のサービス(すべてではない)の基本的な使い方を説明する専用紹介記事もあります。botoのEC2インターフェースの紹介現在のユースケースを扱います。

また、以下を読むこともできます。ボート構成環境(資格情報など)を設定します。

使用法

あなたは探検することができますボートPython経由REPL(読み取り - 評価 - 印刷ループ)、つまりpython

スニペットに満足したら、スタンドアロン使用のためにPythonスクリプトに変換できます。

はい

以下は、ユースケースを大まかに解決する例です(ユーザー環境で説明されているように資格情報が設定されているとします)。ボート構成):

$ python
Python 2.7.2 (default, Jun 12 2011, 14:24:46)
Type "help", "copyright", "credits" or "license" for more information.
>>> import boto
>>> ec2 = boto.connect_ec2()
>>> instances = ec2.get_all_instances()
>>> instances
[Reservation:r-916d01f2, Reservation:r-3f7e055c, Reservation:r-c37209a0]

まあ、get_all_instances()実際にはリストを返します。boto.ec2.instance.予約したがって、これには通常、他の場所では見られない迷惑な間接参照(EC2 APIに由来)があります。文書はすでに決定的ですが、内部検査でそれらを特定する方法を見てみましょう。

>>> dir(instances[0])
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', 
'__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', 
'__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 
'connection', 'endElement', 'groups', 'id', 'instances', 'item', 'owner_id', 
'region', 'startElement', 'stop_all']
>>> insts = instances[0].instances
>>> insts
[Instance:i-5d9a593a]

これに近いので、最終的に次の属性値を見たいと思うでしょうi-5d9a593a(簡潔さとプライバシーのために、ほとんどの属性は省略されます)。

>>> vars(insts[0])
{'kernel': u'aki-825ea7eb', 'private_dns_name': '', 'id': u'i-5d9a593a', 
'monitored': False, 'state': u'stopped', 'architecture': u'x86_64',  
 'public_dns_name': '', 'ip_address': None, 'placement': u
'us-east-1a', 'ami_launch_index': u'0', 'dns_name': '', 'region': RegionInfo:us-east-1
# ...
}

正確ではありませんが、Pythonデータプリティプリンタ(pprint)構造する:

>>> import pprint
>>> pp = pprint.PrettyPrinter(indent=4)
>>> pp.pprint(vars(insts[0])) {   
    '_in_monitoring_element': False,
    'ami_launch_index': u'0',
    'architecture': u'x86_64',
    'dns_name': '',
    'hypervisor': u'xen',
    'id': u'i-5d9a593a',
    'instance_class': None,
    'instance_type': u'm1.medium',
    'ip_address': None,
    'kernel': u'aki-825ea7eb'
    # ...
    }

答え2

sponge行を配列に読み込み、出力して一時ユーティリティを作成できます。たとえば、次のようになります。

sponge() {
    local line lines
    while IFS= read -r line; do
        lines+=( "$line" )
    done
    printf '%s\n' "${lines[@]}"
}

それからcommand1 | sponge | command2

答え3

これはbash / ksh / zshのための非常に粗雑なキャッシュツールです。

typeset -A output_cache
cache () {
  local IFS='
  ' ret=0
  if [[ -z ${output_cache["$*"]} ]]; then
    output_cache["$*"]=$(unset IFS; "$@")
    ret=$?
  fi
  echo "${output_cache["$*"]}"
  return $ret
}
uncache () {
  local IFS='
  '
  unset output_cache["$*"]
}

例:

$ cache mycommand --options        # takes a while
$ cache mycommand --options        # instantaneous
$ uncache mycommand --options      # remove a cache entry

限界:

  • これは、コマンドを2回実行すると、毎回同じ出力が生成される場合にのみ意味があります。
  • キャッシュはシェルインスタンス間で共有されません。
  • これはパイプ、ループなどではなく単純なコマンドでのみ機能します(使用しない限りcache sh -c …)。
  • 単語の区切り(vs.など)のみが異なるキャッシュエントリを区別しないでくださいmycommand "foo bar"mycommand "foo" "bar"これは実際に大きな問題にならないでください。
  • コマンドを初めて呼び出すと、戻りコードが返されます。キャッシュされた呼び出しは0を返します。元の戻りコードを返すには、戻りコードを保存する連想配列を追加します。別の可能な動作は、コマンドがゼロ以外の状態を返す場合にのみ、コマンド出力をキャッシュに格納することです。
  • 標準エラーや他のファイル記述子の出力ではなく、標準出力のみが保存されます。
  • 空の出力はキャッシュされたとは見なされません。
  • 出力端の改行数は 1 に正規化されます。 (これは簡単に修正できますが、実際にはこの方法が良いでしょう。)
  • 以降、エイリアスは使用できませんcache。ここに希望があります。常にコマンドをキャッシュしたい場合は、エイリアスをとして指定できますcache mycommand
  • 潜在的に有用な有効期限メカニズム(依存関係の検出、最大項目数の維持、項目寿命の提供など)が多くあり、この回答ではこれを実装しません。

答え4

#!/bin/sh
PROG="$(basename $0)"
DIR="${HOME}/.cache/${PROG}"
mkdir -p "${DIR}"
EXPIRY=600 # default to 10 minutes
[ "$1" -eq "$1" ] 2>/dev/null && EXPIRY=$1 && shift
CMD="$@"
HASH=$(echo "$CMD" | md5sum | awk '{print $1}')
CACHE="$DIR/$HASH"
test -f "${CACHE}" && [ $(expr $(date +%s) - $(date -r "$CACHE" +%s)) -le $EXPIRY ] || "$CMD" > "${CACHE}"
cat "${CACHE}"

関連情報