Нужен элегантный способ перегрузки команды в скрипте Bash, динамически создаваемом и вызываемом другим инструментом - PullRequest
0 голосов
/ 29 февраля 2020

Было много сообщений о том, как перегрузить команды в Bash, либо создав псевдоним или функцию, либо просто изменив сам скрипт или как он вызывается; эти методы имеют смысл для меня, но не применимы к проблеме, которую я пытаюсь решить.

В полупроводниковой промышленности принято работать с инструментами EDA, которые предоставляют команды API внутри интерпретатора Tcl; в моем случае инструмент EDA генерирует сценарий Bash, а затем выполняет его один вызов API, поэтому у меня есть доступ к сценарию только после выполнения сценария, и я не могу изменить способ его вызова, поскольку это происходит под капотом; нет также благословенного метода для изменения интересующих команд, которые записаны в сценарий.

Что еще больше усложняет то, что этот сценарий генерируется и вызывается инструментом EDA внутри контейнера Singularity; Кроме того, вызываемая команда находится в другом контейнере инструментов EDA, поэтому эту команду 'vsim' необходимо преобразовать в вызов s sh нашего менеджера рабочей нагрузки (slurm). Пример: vsim <args> Должен быть преобразован в: ssh <some-host> <ssh-options> "srun <srun-options> vsim <args>"

Опять же, установка псевдонима или функции с именем 'vsim' в родительской оболочке не работает для меня; псевдоним / функция не был унаследован подпроцессом (мне трудно это принять). Я также попытался создать символическую ссылку с именем 'vlog', указывающую на скрипт диспетчера stati c; это сработало, я бы предпочел не жестко кодировать путь к диспетчеру как путь к файлу; Я бы предпочел использовать переменную, например vlog -> .../<resource>/$VERSION/bin/dispatch_for_flows, но символические ссылки не являются динамическими c.

Я думаю, что мне все же следует использовать подход символической ссылки, но вместо того, чтобы указывать на диспетчера, я бы указать на оболочку, которая выполняет одну строку exe c интерполированного пути к диспетчеру, но я все еще не верю, что установка псевдонима не решила проблему. В течение многих лет я писал Csh сценарии с полными путями к командам, чтобы обойти псевдонимы пользователей; с Bash похоже, что псевдонимы никогда не наследуются, даже если в родительской оболочке или даже в / etc / profile есть включенный параметр'andand_alias '. Что мне здесь не хватает?

Может кто-нибудь заставить приведенный ниже пример работать? Я бы хотел, чтобы скрипт наследовал псевдоним от родительской оболочки и выполнялся без ошибки «команда не найдена», без изменения скрипта или способа его вызова. Опять же, у меня нет доступа к сценарию до его выполнения, и я не могу контролировать, как он вызывается; bash - это родительская оболочка, bash - это сценарий, и у меня есть доступ root в ОС, поэтому я могу изменить версию bash, если необходимо (используя 4.4.19 (1) -релиз (x86_64) -redhat- linux -gnu))

$ alias hello='echo world'
$ hello
world
$ shopt | grep expand_aliases
expand_aliases  on
$ cat test.bash
#!/usr/bin/bash
set -x
alias
shopt | grep expand_aliases
shopt -s expand_aliases
shopt | grep expand_aliases
hello

$ ./test.bash
+ alias
+ shopt
+ grep expand_aliases
expand_aliases  off
+ shopt -s expand_aliases
+ shopt
+ grep expand_aliases
expand_aliases  on
+ hello
./test.bash: line 7: hello: command not found

1 Ответ

2 голосов
/ 29 февраля 2020

Может кто-нибудь заставить работать приведенный ниже пример?

Нет, это невозможно с псевдонимами - вы не можете экспортировать псевдоним. Но вы можете экспортировать функцию.

$ hello() { echo world; }
$ export -f hello
$ ./test.bash
world

Вы можете создать пользовательскую команду в PATH:

$ printf "%s\n" "#!/bin/bash" "echo world" > /usr/local/bin/hello
$ chmod +x /usr/local/bin/hello

, а также добавить пользовательскую команду и добавить новый путь с командой к ПУТЬ и экспорт.

...