Як запустити псевдонім у скрипті оболонки?


101

У мене є виконавчий файл mpiexec, повний шлях якого ~/petsc-3.2-p6/petsc-arch/bin/mpiexec. Оскільки я хочу виконувати цю команду в різних каталогах (без повторного введення всього шляху), я встановлюю псевдонім у своєму домашньому .bashrcфайлі:

alias petsc="~/petsc-3.2-p6/petsc-arch/bin/mpiexec"  

що дозволяє мені легко виконувати цей mpiexecфайл у командному рядку, набравши:

petsc myexecutable

Я спробував написати файл сценарію оболонки, названий script, використовуючи свій новий псевдонім petscяк команду. Надавши моєму сценарію оболонки відповідні дозволи (використовуючи chmod), я спробував запустити сценарій. Однак це дало мені таку помилку:

./script: line 1: petsc: command not found

Я знаю, що я міг просто написати повний шлях до mpiexecфайлу, але громіздко писати повний шлях щоразу, коли я хочу написати новий сценарій. Чи є спосіб використовувати свій псевдонім petscу файлі сценарію? Чи є спосіб змінити своє .bashrcчи .bash_profileзробити це?


Як щодо додавання псевдоніма до .bash_aliases? А як щодо зведення абсолютного шляху замість відносного шляху на кшталтalias petsc='/home/user/petsc-3.2-p6/petsc-arch/bin/mpiexec'
Нітін Венкатеш,

@nitstorm: Жодне рішення, здається, не працює ... Я все одно отримую ту ж помилку, що і раніше
Пол

Відповіді:


74
  1. У сценарії оболонки використовуйте повний шлях, а не псевдонім.

  2. У своєму скрипті оболонки встановіть змінний, інший синтаксис

    petsc='/home/your_user/petsc-3.2-p6/petsc-arch/bin/mpiexec'
    
    $petsc myexecutable
  3. Використовуйте функцію у своєму сценарії. Напевно, краще, якщо petscце складно

    function petsc () {
        command 1
        command 2
    }
    
    petsc myexecutable
  4. Джерело псевдонімів

    shopt -s expand_aliases
    source /home/your_user/.bashrc

Ви, мабуть, не хочете надсилати своє джерело .bashrc, тож, IMO, одна з перших 3 була б кращою.


16
Точка 4 не працює, якщо ви не використовуєте один і shopt -s expand_aliasesтой же сценарій.
enzotib

Ваша пропозиція 2) працює, але я хочу мати можливість використовувати одну і ту ж команду в декількох скриптах оболонки без необхідності писати перший рядок petsc = "...". Чи є спосіб це зробити?
Пол

1
@enzotib - дякую, я додав це до своєї відповіді.
Пантера

1
У пункті 2 ви не встановлюєте псевдонім, а змінну.
pabouk

1
Не вимагається ОП, але стосується назви питання: Точка 2 не працюватиме з командами, що містять |. Тут використання shopt -s expand_aliases& локальний псевдонім, наприклад alias myalias='echo abc|rev'- вимагає розриву рядків перед використанням (див. Псевдоніми в man bash). Пункт 4: Вироблений файл може запобігти неінтерактивне виконання, тобто в сценарії. Подивіться на ранні exitабо return, наприклад , [ -z "$PS1" ] && return(чеки , якщо первинна підказка не встановлюється з вказівкою не-інтерактивної оболонки) або може бути перевірка iв $-( $-містить опції оболонки, iозначає інтерактивний). Дивіться man bashдля цих змінних.
дійсний

61

Псевдоніми застаріли на користь функцій оболонок. З bashсторінки керівництва:

For almost every purpose, aliases are superseded by shell functions.

Щоб створити функцію та експортувати її в підрозділи, введіть наступне ~/.bashrc:

petsc() {
    ~/petsc-3.2-p6/petsc-arch/bin/mpiexec "$@"
}
export -f petsc

Тоді ви можете вільно викликати свою команду зі своїх сценаріїв.


Це майже працює ... Єдина проблема полягає в тому, що мені потрібно вміти передавати різні прапори виконуваному файлу "mpiexec" ... Наприклад, мені потрібно вміти виконувати щось на кшталт "petsc -n 40 myexecutable" за допомогою псевдонім "petsc"
Пол

4
@Paul: Я додав "$@"просто для обробки аргументів.
enzotib

12

Функції оболонки та псевдоніми обмежені оболонкою і не працюють у виконаних сценаріях оболонок. Альтернативи для вашого випадку:

  • (якщо ви не намагаєтесь використовувати mpiexecзамість petsc) Додати $HOME/petsc-3.2-p6/petsc-arch/binдо своєї PATHзмінної. Це можна зробити за допомогою редагування ~/.profileта додавання:

    PATH="$HOME/petsc-3.2-p6/petsc-arch/bin:$PATH"

    Повторно увійдіть, щоб застосувати ці зміни

  • Створіть каталог ~/binі

    • складіть скрипт для обгортки, який petscмістить:

      #!/bin/sh
      exec ~/petsc-3.2-p6/petsc-arch/bin/mpiexec "$@"
    • якщо програма дозволяє це, ви можете пропустити оболонку оболонки та зробити символьне посилання за допомогою команди:

      ln -s ~/petsc-3.2-p6/petsc-arch/bin/mpiexec ~/bin/petsc

9

У Баш 4 ви можете використовувати спеціальну змінну: $BASH_ALIASES.

Наприклад:

$ alias foo="echo test"
$ echo ${BASH_ALIASES[foo]}
echo test
$ echo `${BASH_ALIASES[foo]}` bar
test bar

Альтернативно визначте як змінну, тоді використовуйте підстановку команд або eval.

Так, наприклад, замість того, щоб визначати псевдоніми, такі як:

alias foo="echo test"

визначте це як:

foo="echo test"

замість цього. Потім виконайте це:

find . -type f -exec sh -c "eval $foo" \;

або:

find . -type f -exec sh -c "echo `$foo`" \;

Хоча псевдоніми застаріли на користь функцій оболонки, ця відповідь є єдиною, яку слід прийняти. Навіть старий Debian 8 має версію 4 bash, тому ${BASH_ALIASES[alias]}це хороший варіант. Інакше мені довелося редагувати багато рядків мого .bash_aliases, щоб застосувати інші речі. Дякую.
erm3nda

8

Ви можете змусити bash виконувати свій скрипт як інтерактивну оболонку із прапорцем -i. Це допоможе вашому файлу .bashrc визначити псевдоніми та інші функції.

Приклад:

~ $ grep ll .bashrc
alias ll='ls -lah'
~ $ cat script.sh 
#!/bin/sh

ll
~ $ bash script.sh 
script.sh: line 3: ll: command not found
~ $ bash -i script.sh
..directory contents..

Більше інформації:

$ man bash

2
.bashrcтакож читається під час неінтерактивного виконання команд SSH (тому вгорі є перевірка на інтерактивність)
муру

6
ALIASES
   ...
   Aliases are not expanded when the shell is not interactive, unless the expand_aliases shell option is set using shopt (see the description of shopt under SHELL BUILTIN COMMANDS
   below).

Отже, справжня відповідь на це питання для тих, хто хоче використовувати фактичні псевдоніми в скриптах оболонки замість альтернатив для них:

#!/bin/bash

shopt -s expand_aliases

alias foo=bar

foo whatever

Що стосується того, чому я хотів би це зробити: Через незвичні обставини мені потрібно обдурити Dockerfile, думаючи, що це сценарій оболонки.


4
  1. В .bash_aliases:

    petsc {
    ~/petsc-3.2-p6/petsc-arch/bin/mpiexec "$@"
    }

    Або поставити функцію .bashrc. Зазвичай у .bashrcналаштуваннях bashзберігаються лише налаштування .

  2. У Терміналі: source .bash_aliases

  3. Назви це: petsc arg(s)

Перевага: Вам не потрібно export -f petscв .bash_aliases. Псевдоніми застарілі, але використання .bash_aliasesфункцій нормально.


Мені подобається це рішення, я спробую його пізніше
Greenonline

2
  1. Використовуйте псевдоніми в сценарії оболонки.
  2. Джерело сценарію у вашій поточній, інтерактивній оболонці замість виконання.

Тож якщо у вас є файл, викликаний script.shвашими командами, який включає використання псевдонімів, просто введіть:

source script.sh

@DavidFoerster Цей метод працює чудово. Використання скрипту за допомогою .або sourcebuiiltin призводить до того, що поточна оболонка виконує всі команди в ній. Якщо розширення псевдоніму відбудеться в оболонці, в якій .або sourceзапущено, воно відбувається. Однак важливо усвідомити, що цей метод корисний лише іноді, оскільки часто потрібно або хоче виконати сценарій у власній оболонці, із власним оточенням. Сценарії оболонки, написані з наміром виконати звичайним способом, зазвичай не можуть надходити замість них - вони часто не спрацьовують правильно.
Елія Каган

@EliahKagan: Дякую Тепер я розумію, що має означати відповідь. Додам пояснення.
Девід Фоерстер

1

(EDIT: видалені функції, оскільки я неправильно читав виклики mpiexec.)

Якщо єдине, що вам потрібно, це менший набір тексту, чому б вам просто не помістити папку в $ PATH? Або зробити символьне посилання на mpiexec з якоїсь папки в $ PATH? Або (мій улюблений) покласти псевдонім у сценарій, який ви джерелом викликаєте у викличному скрипті?


1
Причина, чому я не можу помістити його у свій $ PATH, полягає в тому, що у мене є інший файл 'mpiexec' в іншому каталозі, який є alredy у моєму $ PATH. Якщо я додам шлях до цього нового 'mpiexec', він, ймовірно, спробує виконати їх обох ... чи не так?
Пол

1
Не можу зрозуміти, чому не просто використовувати "$@".
enzotib

2
Павло, він спробує виконати той, який перший в ПАТ, а не обидва.
розкуркулити

enzotib, ах я неправильно прочитав те, як називався mpiexec, я подумав, що потрібні всі аргументи як одна. Відредагую мою відповідь :)
зніміть
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.