Intereting Posts
Помощь в исправлении систем RHEL 6.x с воздушным потоком на удаленных объектах Перемещение папок с определенным ключевым словом в имени в новую папку Автоматическое обновление системы Debian Может ли rsync определить, где остановился прерванный процессор? недокументированное изменение поведения «локального», встроенного в bash 4.3? resolv.conf ограничено шестью доменами с общим количеством символов 256 Нет звука в Lenovo Ideapad Alpine 3.8.0: установка приложения, ошибка: «Невозможно сгенерировать метаданные ORC для CONFIG_UNWINDER_ORC = y» Cron работает в 12.00, несмотря на изменение времени Удаление набора записей, если найденный шаблон Использование цикла для сортировки и сохранения файлов с помощью Grep Есть ли шанс исправить двойную загрузку, не нужно включать и выключать UEFI для переключения ОС? как регистрировать даты перезагрузки Как удалить двойные кавычки из файла, но не внутри двойных кавычек diff -r только для определенных типов файлов

Есть ли у bash встроенная команда кэширования (вроде как mktemp или sponge)?

Я использую средства командной строки amazon ec2, а инструмент ec2-describe-instances – немного болезненный из-за 2-5 секунд, который требуется для выполнения запроса и отображения вывода.

Я изучаю использование инструмента fec2din , описанного в этом вопросе, для форматирования вывода ec2-describe-instances и задавался вопросом, каким лучшим способом будет кэшировать вывод из этого вызова.

fec2din использует mktemp для создания временного файла, а затем использует awk для форматирования вывода.

Есть ли какой-нибудь инструмент, который я мог бы использовать с параметром TTL, который будет запускать ec2-describe-instances если метка времени в файле кеша была старше определенного времени?

Это было бы аккуратно, если бы была небольшая утилита для этого (например, sponge для помощи с stdout ).

Хотя это не касается вашего вопроса как такового, я могу настоятельно рекомендовать использовать Amazon EC2 через отличный boto , а это пакет Python, который предоставляет интерфейсы для Amazon Web Services .

Он в значительной степени покрывает ту же основу, что и API Amazon EC2 API , но не страдает от болезненных задержек из-за использования современных и быстрых API AWS REST, в то время как инструменты API EC2 написаны на Java и используются для использования старого и медленные API-интерфейсы SOAP (не знаю, могли ли они изменить настройки в этом отношении уже, но ваш опыт, а также все еще требуемые сертификаты AWS X.509, похоже, указывают на другое).

Кроме того, вам больше не нужно использовать эти сертификаты AWS X.509 , а скорее использовать более распространенный и гибкий подход с помощью идентификатора ключа доступа AWS и ключа секретного доступа AWS , который также может (и обычно должен быть ), предоставляемые через AWS Identity and Access Management (IAM) , чтобы избежать раскрытия ваших основных учетных данных AWS.

Кроме того, boto это очевидный кандидат на организацию вашего повседневного использования AWS с помощью скриптов Python – это тоже можно сделать с bash , но вы получите идею;)

Документация

Вы можете найти документацию и примеры в boto: Интерфейс Python для веб-сервисов Amazon , который обеспечивает достойные (то есть более или менее полные) ссылки на API (например, для EC2 ), а также специальные вступительные статьи, объясняющие базовое использование нескольких служб (но не все еще), например, введение в интерфейс EC2 boto охватывает используемый вариант.

Кроме того, вы можете прочитать Boto Config для настройки вашей среды (учетные данные и т. Д.).

Применение

Вы можете изучить boto через цикл Python Read-eval-print (REPL) , то есть путем запуска python .

Как только вы удовлетворитесь своими фрагментами, вы можете преобразовать их в скрипт Python для автономного использования.

пример

Ниже приведен пример, примерный пример использования вашего варианта использования (предполагается, что вы настроили учетные данные в своей среде, как описано в Boto Config ):

 $ 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.Reservation , так что здесь есть раздражающая косвенность (вытекающая из 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's Data довольно принтер (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' # ... } 

Утилиту sponge можно использовать, читая строки в массив, а затем выводит ее, например:

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

Затем запустите его как command1 | sponge | command2 command1 | sponge | command2 command1 | sponge | command2 .

Вот очень грубое средство кэширования для 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 … ).
  • Записи кэша, которые отличаются только mycommand "foo bar" слов (например, mycommand "foo bar" и mycommand "foo" "bar" ), не различаются. Это не должно быть реальной проблемой на практике.
  • Первый вызов команды возвращает код возврата. Кэшированные вызовы возвращают 0. Если вы хотите вернуть исходный код возврата, добавьте ассоциативный массив для хранения кодов возврата. Другим возможным поведением было бы сохранение вывода команды в кеше, только если команда возвращает ненулевой статус.
  • Сохраняется только стандартный вывод, вывод на стандартную ошибку или другие дескрипторы файлов – нет.
  • Пустой выход не считается кэшированным.
  • Количество новых строк в конце вывода нормализуется до 1. (Это легко исправить, но, вероятно, лучше всего на практике).
  • Вы не можете использовать псевдоним после cache . Это облако имеет серебряную подкладку: если вы обнаружите, что всегда хотите кэшировать команду, вы можете использовать ее для cache mycommand .
  • Истека нет. Существует много потенциально полезных механизмов истечения срока действия (попытайтесь выявить релевантность, сохранить максимальное количество записей, дать записи время для жизни …), я не буду реализовывать их как часть этого ответа.
 #!/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}"