Тишина у каждого своя, у всех в душе свои оркестры…
Как мы с тобой знаем, в начале скрипта принято использовать строку shebang/hashbang. Это то самое, которое #!/bin/bash. Конечно его не обязательно ставить, но рекомендуется. Ранее этот вопрос разбирался здесь.
Так, но порой вместо привычной нам конструкции, можно встретить нечто подобное:
Да, с питончиком тоже такая чача бывает. Но что это за сракафак и зачем? В нашем случае такое хитрое указание интерпретатора имеет смысл.
Основная идея env bash это улучшение переносимости. Никто не может гарантировать, что интерпретатор находится по захардкоженому пути.
Указал ты допустим в скрипте #!/bin/bash, закинул скрипт на сервер, а эндпоинта bin/bash нет. По этой причине господа ребята используют хак с env bash. Использование env позволяет снизить риски за счет запуска команды на основе данных из переменной среды PATH.
Ну и используя env в скрипте можно указывать любые версии интерпретатора. Возможно у тебя стоит две версии bash, ну или как распространено с питончиком. Деприкейтед 2.7 и трёшка. Думаю мысль ты уловил. Чтобы не править скрипты, можно подменять версии интерпретаторов и даже сами интерпретаторы.
Давай посмотрим на практике.
1. Создаем папку bin в домашнем каталоге
2. Копируем интерпретатор sh в ~/bin, но обзываем его bash
3. Экспортируем новый путь ~/bin в PATH
4. Запускам bash через env
Дела… у нас запустился интерпретатор sh. То есть ~/bin/bash (обращаем внимание на знак ~ = домашняя директория пользователя) был найден раньше, чем просто /bin/bash.
Если посмотреть PATH мы увидим следующее:
Наш домашний каталог с бинарниками стал приоритетным. И если теперь в скриптах указать #!/usr/bin/env bash то запустится sh из ~/bin. Ничего сложного. Но на практике обычно никто такой хераборой не занимается. Чисто для примера, ну или для совсем уж костылей, когда нужно быстро и вчера.
Преимущества c env:
- Запуск интерпретатора не из конкретно указанного места, а из того что встретилось первым в переменной окружения PATH.
Недостатки:
- Путь /usr/bin/env банально может не существовать. Но обычно существует.
Ну и если используешь env, в него можно прокинуть параметры, делается через ключик -S:
Venv в Python работает по такому же принципу, реврайтит PATH и позволяет использовать разные версии.
Если посмотреть PATH (
То есть к нашему PATH добавился каталог /tmp/.venv/bin, который стал приоритетнее чем /home/user/bin.
Вот так вот это всё и работает под капотом. Я эти env по большей части никогда не использую, хреначу #!/bin/bash и погнали, пока всегда и везде работало. Конец!
tags: #bash #linux
—
💩 @bashdays
Как мы с тобой знаем, в начале скрипта принято использовать строку shebang/hashbang. Это то самое, которое #!/bin/bash. Конечно его не обязательно ставить, но рекомендуется. Ранее этот вопрос разбирался здесь.
Так, но порой вместо привычной нам конструкции, можно встретить нечто подобное:
#!/usr/bin/env bash
#!/usr/bin/env python
#!/usr/bin/env python3
Да, с питончиком тоже такая чача бывает. Но что это за сракафак и зачем? В нашем случае такое хитрое указание интерпретатора имеет смысл.
Основная идея env bash это улучшение переносимости. Никто не может гарантировать, что интерпретатор находится по захардкоженому пути.
Указал ты допустим в скрипте #!/bin/bash, закинул скрипт на сервер, а эндпоинта bin/bash нет. По этой причине господа ребята используют хак с env bash. Использование env позволяет снизить риски за счет запуска команды на основе данных из переменной среды PATH.
Ну и используя env в скрипте можно указывать любые версии интерпретатора. Возможно у тебя стоит две версии bash, ну или как распространено с питончиком. Деприкейтед 2.7 и трёшка. Думаю мысль ты уловил. Чтобы не править скрипты, можно подменять версии интерпретаторов и даже сами интерпретаторы.
Давай посмотрим на практике.
mkdir ~/bin
cp /bin/sh ~/bin/bash
export PATH=~/bin:$PATH
env bash
1. Создаем папку bin в домашнем каталоге
2. Копируем интерпретатор sh в ~/bin, но обзываем его bash
3. Экспортируем новый путь ~/bin в PATH
4. Запускам bash через env
Дела… у нас запустился интерпретатор sh. То есть ~/bin/bash (обращаем внимание на знак ~ = домашняя директория пользователя) был найден раньше, чем просто /bin/bash.
Если посмотреть PATH мы увидим следующее:
echo $PATH
/root/bin:/root:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
Наш домашний каталог с бинарниками стал приоритетным. И если теперь в скриптах указать #!/usr/bin/env bash то запустится sh из ~/bin. Ничего сложного. Но на практике обычно никто такой хераборой не занимается. Чисто для примера, ну или для совсем уж костылей, когда нужно быстро и вчера.
Преимущества c env:
- Запуск интерпретатора не из конкретно указанного места, а из того что встретилось первым в переменной окружения PATH.
Недостатки:
- Путь /usr/bin/env банально может не существовать. Но обычно существует.
Ну и если используешь env, в него можно прокинуть параметры, делается через ключик -S:
#!/usr/bin/env -S var1=a var2=b bash --help
Venv в Python работает по такому же принципу, реврайтит PATH и позволяет использовать разные версии.
> index.py
python3 -m venv .venv
source .venv/bin/activate
import sys
print(sys.executable)
/tmp/.venv/bin/python
Если посмотреть PATH (
echo $PATH
) при активации venv, то увидим совершенно другой PATH:/tmp/.venv/bin:/home/user/bin:/usr/local/opt/libpcap/bin:/home/user/.pyenv/bin:/opt/homebrew/opt/openjdk/bin
То есть к нашему PATH добавился каталог /tmp/.venv/bin, который стал приоритетнее чем /home/user/bin.
Вот так вот это всё и работает под капотом. Я эти env по большей части никогда не использую, хреначу #!/bin/bash и погнали, пока всегда и везде работало. Конец!
tags: #bash #linux
—