Надеюсь, этот вопрос не слишком общий. Я совсем новичок в написании сценариев оболочки и имею опыт программирования архитектуры компьютера/несценарного программирования. Я заметил в сценариях на своей работе, что редко сценарии пишутся с созданием под-оболочки вокруг всего сценария. В сценариях, которые я пишу, когда я могу обернуть его под-оболочкой, я так и делаю, поскольку это не дает ему мешать другим сценариям, которые вызывают мой (на всякий случай). Разве это не распространенная практика из-за некоторых накладных расходов, связанных с этим подходом? Мне трудно найти это в сети.
Пример:
#!/bin/bash
( #Start of subshell
echo "Some stuff here"
) #End of subshell
решение1
Подоболочки имеют накладные расходы.
В моей системе минимальная стоимость fork-exec (когда вы запускаете программу с диска, когда файл не холодный) составляет около , 2ms
а минимальная стоимость fork составляет около 1ms
.
С подоболочками вы говорите только о стоимости разветвления, так как не нужно exec
редактировать ни один файл. Если подоболочки поддерживаются на разумном низком уровне, 1ms
это довольно незначительно в программах, ориентированных на человека. Я считаю, что люди не могут заметить ничего, что происходит быстрее 50ms
(и именно столько времени требуется современным интерпретаторам скриптовых языков, чтобы даже начать (я говорю python
и о Ruby rvm
здесь), с новейшими, nodejs
занимающими около 100ms
).
Однако это добавляет циклы, и тогда вы можете захотеть заменить, например, довольно распространенный обратный вызов или $()
шаблон, где вы return
что-то из функции печатаете в stdout для родительской оболочки, чтобы перехватить его с помощью bashisms printf -v
(или использовать быструю внешнюю программу для обработки всего пакета).
Thebash-дополнениеПакет специально избегает этой стоимости подоболочки, возвращая переданные имена переменных с помощью техники, описанной вhttp://fvue.nl/wiki/Bash:_Передача_переменных_по_ссылке
Сравнивая
time for((i=0;i<10000;i++)); do echo "$(echo hello)"; done >/dev/null
с
time for((i=0;i<10000;i++)); do echo hello; done >/dev/null
должен дать вам хорошую оценку fork
накладных расходов вашей системы.
решение2
Запуск превосходного кода, предоставленного PSkocik, на моей системе показал незначительные результаты.
Однако этот пример действительно поражает — собственные команды против команд подоболочки:
MyPath="path/name.ext"
# this takes forever
time for((i=0;i<10000;i++)); do echo "$(basename ${MyPath} )"; done >/dev/null
#this is over 100x less time
time for((i=0;i<10000;i++)); do echo "${MyPath##*/}"; done >/dev/null