Хотя это aliasодин из способов сделать это, это также можно сделать eval- просто вы не столько хотите выполнить evalкоманду, сколько хотите объявитьeval команду .
Мне нравится aliases - я использую их все время, но мне больше нравятся функции - особенно их способность обрабатывать параметры и то, что их необязательно расширять в командную позицию, как это требуется для aliases.
Так что я подумал, может быть, вы тоже захотите попробовать это:
_time() if set -- "${IFS+IFS=\$2;}" "$IFS" "$@" && IFS='
'; then set -- "$1" "$2" "$*"; unset IFS
eval "$1 $TIME ${3#"$1"?"$2"?}"
fi
$IFSНемного в основном о $*. Важно, что ( subshell bit )это также является результатом расширения оболочки, и поэтому для расширения аргументов в используемую мной синтаксическую строку "$*" (не eval "$@", кстати, если вы не уверены, что все аргументы могут быть объединены в пробелах) , Разделитель между аргументами in "$*"является первым входящим байтом $IFS, и поэтому может быть опасно продолжать работу без определения его значения. Таким образом, функция сохраняет $IFS, устанавливает его в \newline достаточно долго , чтобы set ... "$*"в "$3", unsetоно что , сбрасывает его значение , если она ранее была.
Вот небольшая демонстрация:
TIME='set -x; time'
_time \( 'echo "$(echo any number of subshells)"' \
'command -V time' \
'hash time' \
\) 'set +x'
Видите ли, я поместил две команды в значение $TIMEтам - любое число в порядке - даже нет - но убедитесь, что оно экранировано и указано правильно - и то же самое относится и к аргументам _time(). Все они будут объединены в одну командную строку, когда будут выполнены, но каждый аргумент получит свою собственную электронную \nлинию, и поэтому их можно относительно легко разложить. Или же вы можете объединить их все в одно, если хотите, и разделить их на электронные \nлинии или точки с запятой или что-то еще. Просто убедитесь, что один аргумент представляет команду, которую вы бы чувствовали комфортно, если бы вы вызывали ее в скрипте при вызове. \(Например, хорошо, если это в конечном итоге с \). В основном нормальные вещи.
Когда evalэтот фрагмент получен, он выглядит так:
+ eval 'IFS=$2;set -x; time (
echo "$(echo any number of subshells)"
command -V time
hash time
)
set +x'
И его результаты выглядят как ...
ВЫВОД
+++ echo any number of subshells
++ echo 'any number of subshells'
any number of subshells
++ command -V time
time is a shell keyword
++ hash time
bash: hash: time: not found
real 0m0.003s
user 0m0.000s
sys 0m0.000s
++ set +x
hashОшибка указывает на то, что я не имеют /usr/bin/timeустановлен (потому что у меня нет) , и commandдавайте нам знать это время работает. Трейлинг set +x- это еще одна команда, выполняемая после time (что возможно) - важно быть осторожным с командами ввода, когда evalчто-либо используется.