Функция Bash, называющая команду, данную как аргумент

Как Вы пишете функцию в ударе, который выполняет команду, которую он дан как аргумент, где

  • Данная команда может быть псевдонимом
  • Аргументы должны быть переданы точно, как дали; никакая оценка не может быть сделана

Другими словами, как записать as-transparent-as-possible функцию обертки.

Цель функции обертки могла, например, состоять в том, чтобы установить текущий каталог прежде и после данной команды и/или установить переменные среды, или время, сколько времени данная команда берет... Как простой пример здесь я беру функцию, которая просто печатает строку и затем выполняет данную команду.

Первая попытка:

function wrap1 {
   echo Starting: "$@"
   "$@"
}

Вы могли использовать его как wrap1 echo hello. Но проблема - Вы, не может сделать alias myalias echo и затем звоните wrap1 myalias hello: это не разрешило бы псевдоним.

Другое использование попытки eval:

function wrap2 {
   echo Starting: "$@"
   eval "$@"
}

Теперь вызов псевдонима работает. Но проблема - это, оценивает аргументы также. Например, wrap2 echo "\\a" печать просто a вместо \a потому что аргументы оценены дважды.

shopt -s expand_aliases кажется, не помогает здесь также.

Существует ли путь к обоим, оценивают псевдонимы как wrap2, но все еще передают аргументы непосредственно как wrap1?

7
задан Wouter Coekaerts 5 July 2010 в 10:02
поделиться

2 ответа

Вы (э-э, я) можете использовать printf% q, чтобы избежать аргументов. На первый взгляд, экранирование с помощью printf и последующее выполнение eval всегда дает тот же результат, что и прямая передача аргументов.

wrap() {
    echo Starting: "$@"
    eval $(printf "%q " "$@")
}
9
ответ дан 7 December 2019 в 03:10
поделиться

Кажется, это возможно с двойным eval :

eval "eval x=($(alias y | cut -s -d '=' -f 2))"
# now the array x contains the split expansion of alias y
"${x[@]}" "${other_args[@]}"

Так что, возможно, вашу функцию можно было бы записать следующим образом:

wrap() {
    eval "eval prefix=($(alias $1 | cut -s -d '=' -f 2))"
    shift
    "${prefix[@]}" "$@"
}

Однако eval злой, а двойной eval - двойное зло, и псевдонимы не раскрываются в скриптах по какой-то причине.

0
ответ дан 7 December 2019 в 03:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: