Сценарий SH в $PATH не найден в Linux Alpine 3.11

Я согласен с ответом Йохана Мирена и проголосовал за него, но вот дополнительные пояснения, которые могут помочь вам понять проблему.

Кажется, вы путаете область подкачки, т.е. место на диске, предназначенное для хранения менее используемой оперативной и виртуальной памяти. Последний состоит из комбинации областей оперативной памяти и областей на диске.

Процессы резервируют и используют виртуальную память. Они понятия не имеют, где он хранится. Когда им нужно получить доступ к некоторым данным, которых нет в оперативной памяти, процессы (или потоки )приостанавливаются до тех пор, пока ядро ​​не выполнит работу по обеспечению доступности страницы данных.

Когда требуется ОЗУ, ядро ​​освобождает часть ОЗУ, сохраняя менее используемые страницы процесса в области подкачки диска.

Когда процесс резервирует память (, т. е. malloc и тому подобное ), операционные системы без перегрузки помечают неиспользуемые части виртуальной памяти как недоступные. Это означает, что когда процессу, выполнившему выделение, действительно потребуется доступ к зарезервированным страницам, они будут гарантированно присутствовать.

Недостаток заключается в том, что память, не используемая каким-либо другим процессом, не позволяет этим процессам разбивать страницы на страницы, поэтому ОЗУ тратится впустую, если эти процессы неактивны. Хуже того, если сумма резервирований больше, чем размер области подкачки, страницы ОЗУ также будут зарезервированы в соответствии с резервированием, несмотря на то, что они не содержат никаких данных.Это довольно плохой сценарий, потому что у вас будет ОЗУ, которое одновременно непригодно для использования и не используется. Наконец, в худшем случае огромное резервирование не может быть принято, потому что для него больше нет виртуальной памяти (swap + оперативной памяти ). Процесс резервирования обычно аварийно завершается.

С другой стороны, такие операционные системы, как Linux, делают ставку на то, что нехватки виртуальной памяти не будет в любой момент времени. Они принимают большинство резервирований памяти (, но не нереалистичных, это можно более или менее настроить )и в целом это позволяет лучше использовать ОЗУ и ресурсы подкачки.

Это похоже на избыточное бронирование мест авиакомпаниями. Это улучшит заполняемость, но некоторые пассажиры могут быть недовольны. Будем надеяться, что авиакомпании просто бронируют их на другой рейс и, возможно, компенсируют, в то время как Linux просто выбрасывает более тяжелых пассажиров из летящего самолета...

Подводя итог, можно сказать, что Linux резервирует память лениво, «из всех сил», в то время как некоторые другие ОС гарантируют резервирование.

Сценарий реальных случаев, когда чрезмерная коммит имеет смысл, — это когда программа, использующая много виртуальной памяти, выполняет fork, за которым следует exec.

Допустим, у вас есть 4 ГБ оперативной памяти, из которых 3 ГБ доступны для виртуальной памяти и 4 ГБ подкачки. Существует процесс, резервирующий 4 ГБ, но использующий из него только 1 ГБ. Разбивки на страницы нет, поэтому система работает хорошо. В ОС без перегрузки этот процесс не может разветвляться, потому что сразу после разветвления необходимо зарезервировать еще 4 ГБ виртуальной памяти, а осталось только 3 ГБ.

В Linux этот системный вызов fork (или clone )завершится успешно (, но с обманом под прикрытием )и после следующего выполнения (, если таковые имеются ), эти зарезервированные, но неиспользуемые 4 Гб освободятся без вреда.

6
02.05.2020, 20:26
2 ответа

Ваша интерактивная оболочкаdash(маскируется подsh). Оболочка dashговорит

sh: /usr/local/bin/wait-for: not found

при попытке выполнить сценарий, в котором есть ошибочная строка #!-, указывающая на интерпретатор, который не может быть найден. Это случается точно такая же ошибка, которую вы получили бы, когда введенная вами команда не может быть найдена, поэтому легко подумать, что это $PATHпроблема (это не в данном случае ). Другие оболочки имеют более информативные сообщения об ошибках(bashи zsh, в которых говорится, что «плохой интерпретатор :Нет такого файла или каталога», а также сообщается, какой интерпретатор он пытался выполнить ).

Поскольку файл является текстовым файлом DOS , строка#!-указывает оболочке запустить сценарий с /bin/sh\r, где \r— обычное представление символа возврата каретки, который является частью завершения строки в текстовых файлах DOS. В системе Unix возврат каретки является «обычным символом», а вовсе не частью завершения строки, что означает, что он пытается запустить /bin/sh\rдля запуска вашего сценария, а затем терпит неудачу, поскольку этот файл не существует. Следовательно, "не найден" интерпретатор , а не сам скрипт.

Запуск скрипта с явным интерпретатором всегда пропускает строку #!-, поэтому при этом вы не получаете ошибку. Однако в конце каждой строки скрипта по-прежнему будет символ возврата каретки, что при некоторых условиях может привести к сбоям в работе скрипта.

Просто повторно -сохраните файл как текстовый файл Unix или преобразуйте его с помощью dos2unix, чтобы решить вашу проблему.

14
28.04.2021, 23:16

Для тех, кто нашел этот вопрос, моя конкретная проблема заключалась в том, что мой сценарий wait-forкаким-то образом преобразовался в окончание строки Windows.

При повторном сохранении с окончаниями строк unix эта проблема устранена.

Если кто-то может опубликовать лучший ответ, объясняющий, почему окончания строк Windows привели к тому, что файл распознавался только при использовании sh /usr/local/bin/wait-for, а не /usr/local/bin/wait-forили wait-for, я приму это.

1
28.04.2021, 23:16

Теги

Похожие вопросы