У меня есть скрипты python-2.x, которые я копирую между разными системами, Debian и Arch Linux. Debian устанавливает python как '/usr/bin/python', а Arch устанавливает его как '/usr/bin/python2'. Проблема в том, что на Arch linux '/usr/bin/python' также существует, что относится к python-3.x. Поэтому каждый раз, когда я копирую файл, я должен исправить строку shebang, что немного раздражает.
На Arch я использую
#!/usr/bin/env python2
Пока на debian я
#!/usr/bin/env python
Так как "python2" не существует на Debian, есть ли способ передать предпочтительное приложение? Может быть, с расширением оболочки? Я не возражаю, если это зависит, например, от '/bin/sh'. Следующие были бы хороши, но не работают.
#!/usr/bin/env python2 python
#!/usr/bin/env python{2,}
#!/bin/sh python{2,}
#!/bin/sh -c python{2,}
Неудобно то, что "sh -c python {2,}" работает в командной строке: т.е. он вызывает python2, где он доступен, и в противном случае python.
Я бы предпочел не делать ссылку "python2- > python" на Debian, потому что если я дам script кому-то другому, он не будет запущен. Мне также не хотелось бы, чтобы "python" указывал на python2 на Arch, поскольку он ломается с обновлениями.
Есть ли чистый способ сделать это без написания обертки?
Я понимаю, что подобный вопрос был задан раньше, но я не видел никаких ответов, отвечающих моим граничным условиям:) Условная строка shebang для разных версий Python
--- UPDATE
Я взломал уродливое решение оболочки, которое делает эту работу на данный момент.
#!/bin/bash
pfound=false; v0=2; v1=6
for p in /{usr/,}bin/python*; do
v=($(python -V 2>&1 | cut -c 7- | sed 's/\./ /g'))
if [[ ${v[0]} -eq $v0 && ${v[1]} -eq $v1 ]]; then pfound=true; break; fi
done
if ! $pfound; then echo "no suitable python version (2.6.x) found."; exit 1; fi
$p - $* <<EOF
PYTHON SCRIPT GOES HERE
EOF
Объяснение: получить номер версии (v - массив bash) и проверить
v=($(python -V 2>&1 | cut -c 7- | sed 's/\./ /g'))
if [[ ${v[0]} -eq $v0 && ${v[1]} -eq $v1 ]]; then pfound=true; break; fi
запускает найденную программу $p с вводом из stdin (-) и аргументов pass ($ *)
$p - $* <<EOF
...
EOF