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

이 방법으로 문제가 해결되지는 않지만 다음을 사용하는 것이 좋습니다.아마존 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 인터페이스 소개현재 사용 사례를 다루십시오.

또한 다음을 읽어볼 수도 있습니다.보토 구성환경(자격 증명 등)을 설정합니다.

용법

당신은 탐험할 수 있습니다보토파이썬을 통해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

한계:

  • 이는 명령을 두 번 실행하면 매번 동일한 출력이 생성되는 경우에만 의미가 있습니다.
  • 캐시는 셸 인스턴스 간에 공유되지 않습니다.
  • 이는 파이프, 루프 등이 아닌 간단한 명령에만 작동합니다(사용하지 않는 한 cache sh -c …).
  • 단어 분리(예: vs.)만 다른 캐시 항목을 구별하지 마세요 mycommand "foo bar". mycommand "foo" "bar"이는 실제로 큰 문제가 되어서는 안 됩니다.
  • 명령을 처음 호출하면 반환 코드가 반환됩니다. 캐시된 호출은 0을 반환합니다. 원래 반환 코드를 반환하려면 반환 코드를 저장할 연관 배열을 추가하세요. 또 다른 가능한 동작은 명령이 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}"

관련 정보