Зацикливание на псевдонимах в Bash

У меня есть пара aliases определяется в ~/.bash_aliases, Они вызывают одну и ту же команду с разными настройками переменных среды, поэтому мне не нужно вводить их каждый раз. aliases отлично работают в интерактивных оболочках.

alias cmd1='VAR=setting1 cmd $@'
alias cmd2='VAR=setting2 cmd $@'

Теперь я хотел бы объединить все эти варианты команд, каждый с опцией "список". Для этого я установил следующий скрипт на Bash:

#!/bin/bash
shopt -s expand_aliases
source ~/.bash_aliases
CMDs='cmd1 cmd2'
for cmd in CMDs ; do
    $cmd list
done

Однако этот скрипт выдает ошибку

"команда не найдена"

для каждого alias называется. Я перепробовал всевозможные варианты, но не вижу, как здесь работают внутренние компоненты Bash. - Любые идеи приветствуются!

2 ответа

Решение

Псевдонимы не принимают аргументов. Что происходит то $@ при определении псевдонима ничего не расширяется, поэтому он ведет себя точно так же, как alias cmd1='VAR=setting1 cmd ', "Аргументы" просто добавляются к расширению псевдонима.

Вместо этого определите функции:

cmd1 () {
    VAR=setting1 cmd "$@"
}

cmd2 () {
    VAR=setting2 cmd "$@"
}

Кроме того, расширение псевдонима происходит перед расширением параметра, что объясняет ошибку, которую вы видите. однажды $cmd расширяется до cmd1, bash не пытается расширяться cmd1 как псевдоним; он просто обрабатывает его как имя команды, которую не может найти. Поиск функции происходит после применения всех расширений, поэтому ваш цикл

CMDs='cmd1 cmd2'
source ~/.bash_aliases
for cmd in CMDs ; do
  "$cmd" list
done

сейчас будет работать. cmd1 оказывается функцией, и поэтому выполняется с list в качестве аргумента. (Возможно, вы захотите сохранить функции в файле с другим именем, но это не имеет значения. Несмотря на название, .bash_aliases просто должен быть действительный скрипт, а не просто набор псевдонимов.)

Ты можешь использовать eval за это:

#!/bin/bash
shopt -s expand_aliases
alias xxx="printf '%s\n'"
alias yyy="echo"
for cmd in xxx yyy
do
    eval $cmd foo bar bla
done

ВНИМАНИЕ eval зверь и довольно небезопасно. Обратитесь к Bash FAQ 048 за рекомендациями.

Другие вопросы по тегам