Как Вы пишете функцию в ударе, который выполняет команду, которую он дан как аргумент, где
Другими словами, как записать 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?
Вы (э-э, я) можете использовать printf% q, чтобы избежать аргументов. На первый взгляд, экранирование с помощью printf и последующее выполнение eval всегда дает тот же результат, что и прямая передача аргументов.
wrap() {
echo Starting: "$@"
eval $(printf "%q " "$@")
}
Кажется, это возможно с двойным 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
- двойное зло, и псевдонимы не раскрываются в скриптах по какой-то причине.