Вот проблема: у меня есть этот сценарий foo.py
, и если пользователь вызовет его без параметра --bar
, я хотел бы отобразить следующее сообщение об ошибке:
Please add the --bar option to your command, like so:
python foo.py --bar
Сложность заключается в том, что есть несколько способов, которыми пользователь мог вызвать команду:
- Возможно, они использовали
python foo.py
, как в примере - Возможно, они использовали
/usr/bin/foo.py
- У них может быть псевдоним оболочки
frob='python foo.py'
, и на самом деле они запускаютсяfrob
- Возможно, это даже псевдоним git
flab=!/usr/bin/foo.py
, и они использовалиgit flab
В любом случае я бы хотел, чтобы сообщение отражало, как пользователь вызвал команду, чтобы приведенный мной пример имел смысл.
sys.argv
всегда содержит foo.py
, а /proc/$$/cmdline
ничего не знает о псевдонимах. Мне кажется, что единственным возможным источником этой информации был бы сам bash, но я не знаю, как его спросить.
Любые идеи?
ОБНОВЛЕНИЕ Как насчет того, чтобы ограничить возможные сценарии только перечисленными выше?
ОБНОВЛЕНИЕ 2. Многие люди написали очень хорошее объяснение того, почему это невозможно в общем случае, поэтому я хотел бы ограничить свой вопрос следующим:
При следующих предположениях:
- Скрипт запускался интерактивно из bash
- The script was start in one of these 3 ways:
foo <args>
where foo is a symbolic link /usr/bin/foo -> foo.pygit foo
где alias.foo =! / Usr / bin / foo в~/.gitconfig
git baz
где alias.baz =! / Usr / bin / foo в~/.gitconfig
Есть ли способ отличить 1 от (2,3) внутри сценария? Есть ли способ отличить 2 от 3 внутри сценария?
Я знаю, что это долгий путь, поэтому пока принимаю ответ Чарльза Даффи.
ОБНОВЛЕНИЕ 3. На данный момент наиболее многообещающий ракурс был предложен Чарльзом Даффи в комментариях ниже. Если я смогу заставить своих пользователей иметь
trap 'export LAST_BASH_COMMAND=$(history 1)' DEBUG
в их .bashrc
, то я могу использовать в своем коде что-то вроде этого:
like_so = None
cmd = os.environ['LAST_BASH_COMMAND']
if cmd is not None:
cmd = cmd[8:] # Remove the history counter
if cmd.startswith("foo "):
like_so = "foo --bar " + cmd[4:]
elif cmd.startswith(r"git foo "):
like_so = "git foo --bar " + cmd[8:]
elif cmd.startswith(r"git baz "):
like_so = "git baz --bar " + cmd[8:]
if like_so is not None:
print("Please add the --bar option to your command, like so:")
print(" " + like_so)
else:
print("Please add the --bar option to your command.")
Таким образом, я показываю общее сообщение, если мне не удается получить их метод вызова. Конечно, если я собираюсь полагаться на изменение среды моих пользователей, я мог бы также убедиться, что различные псевдонимы экспортируют свои собственные переменные среды, на которые я могу смотреть, но, по крайней мере, этот способ позволяет мне использовать тот же метод для любых другой сценарий, который я могу добавить позже.
history 1
? - person Aaron   schedule 12.07.2018--bar
является обязательным, как насчет того, чтобы всегда добавлять его внутри себя и предоставлять--no-bar
более опытным пользователям, которые этого не хотят и знают, как добавлять аргументы? - person Mark Setchell   schedule 12.07.2018git rebase
попадает в конфликт. Значит, твоя идея у меня не сработает. - person itsadok   schedule 12.07.2018Please add the --bar option to your command, like so: 'cmd --bar'
Большинство людей достаточно умны (опять же, ИМХО), чтобы знать, чтоcmd
является заменой того, что они набирали. - person dawg   schedule 18.07.2018BASH_COMMAND
в среду из ловушкиDEBUG
, но если вы полагаетесь на это, ваша программа будет иметь под рукой поведение только при вызове из оболочка так подготовлена ... так что вряд ли это кажется полезным. - person Charles Duffy   schedule 19.07.2018git
, да, вы можете это сделать. Псевдонимы Shell не встречаются нигде в истории, но поскольку вызов псевдонима git проходит через настоящую внешнюю команду, он появится. - person Charles Duffy   schedule 19.07.2018argv[0]
подход, опосредованный/proc/self/cmdline
или иным образом). - person Charles Duffy   schedule 19.07.2018