Похожий скрипт, без sudo
, но похожие результаты:
$ cat script.sh
#!/bin/bash
sed -e 's/^/--/'
whoami
$ bash < script.sh
--whoami
$ dash < script.sh
itvirta
С bash
остальная часть скрипта идет как вход в sed
, с dash
оболочка интерпретирует его.
Запуск strace
на тех: dash
считывает блок скрипта (восемь КБ здесь, более чем достаточно, чтобы вместить весь скрипт), а затем порождает sed
:
read(0, "#!/bin/bash\nsed -e 's/^/--/'\nwho"..., 8192) = 36
stat("/bin/sed", {st_mode=S_IFREG|0755, st_size=73416, ...}) = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|...
Что означает, что filehandle находится в конце файла, и sed
не увидит никакого ввода. Оставшаяся часть буферизуется внутри dash
. (Если сценарий был длиннее размера блока 8 КБ, оставшаяся часть была бы прочитана sed
.)
Bash, с другой стороны, стремится вернуться к концу последней команды:
read(0, "#!/bin/bash\nsed -e 's/^/--/'\nwho"..., 36) = 36
stat("/bin/sed", {st_mode=S_IFREG|0755, st_size=73416, ...}) = 0
...
lseek(0, -7, SEEK_CUR) = 29
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|...
Если вход поступает из трубы, как здесь:
$ cat script.sh | bash
перемотка невозможна, так как трубы и раструбы не могут быть найдены. В этом случае Bash возвращается к чтению входных данных по одному символу за раз, чтобы избежать перечитывания. ( fd_to_buffered_stream()
in input.c
) Выполнение полного системного вызова для каждого байта в принципе не очень эффективно. На практике я не думаю, что чтение будет большим накладным расходом по сравнению, например, с тем фактом, что большинство вещей, которые делает оболочка, включают в себя порождение совершенно новых процессов.
Аналогичная ситуация такова:
echo -e 'foo\nbar\ndoo' | bash -c 'read a; head -1'
Подоболочка должна убедиться, что read
считывает только первую новую строку, так что head
видит следующую строку. (Это также работает с dash
.)
Другими словами, Bash делает все возможное, чтобы поддерживать чтение одного и того же источника для самого скрипта и для команд, выполняемых из него. dash
нет. zsh
и ksh93
, упакованные в Debian, идут с Bash в этом вопросе.
HTTP-прокси-сервер и memcached
- это разные технологии, которые решают разные проблемы и применяются на разных уровнях вашего программного стека. Обе могут быть полезны.
HTTP-прокси-сервер, расположенный перед вашим приложением, может отвечать на запросы из своего кэша, избавляя ваше приложение от необходимости обрабатывать часть нагрузки на запросы. Это работает только в том случае, если ваше приложение выводит содержимое, которое можно кэшировать, и если конечные пользователи запрашивают содержимое более одного раза. Для того чтобы содержимое было кэшируемым, ваше приложение должно установить соответствующие HTTP-заголовки, чтобы прокси-серверы (и браузеры) знали, что и как долго можно кэшировать.
В случае запросов, которые доходят до вашего приложения (они пропустили кэш HTTP-прокси или не существует HTTP-прокси), ваше приложение должно вычислить содержимое, которое оно должно отправить обратно. Если эти вычисления дорогостоящие, но часть данных может быть кэширована из предыдущих запросов, memcached
- это хороший способ для вашего приложения хранить результаты [части] этих вычислений, чтобы их можно было использовать позже. Ваше приложение должно быть написано специально для этого, а также для подключения к экземплярам memcached
для получения и установки этих данных.
Varnish предназначен для обслуживания файлов веб-страниц, например, html, js, css, изображения и т. д. Он перехватывает HTTP-трафик между интернет-клиентами и сервером внутренних приложений. Varnish слушает http-порт 80 и говорит по протоколу HTTP. Ни браузеры, ни серверные приложения не должны знать, что Varnish существует, если он правильно настроен, он просто работает.
Memcached - это приложение, обычно используемое для кэширования данных, передаваемых с сервера базы данных в приложение, с целью уменьшения количества запросов к БД. Кроме того, поскольку данные кэшируются в памяти, их извлечение происходит намного быстрее. Но это приложение, которое управляет вставкой и извлечением данных из Memcached, другими словами, приложение должно быть написано так, чтобы правильно использовать Memcached. Memcached не поддерживает протокол HTTP.