Этот вопрос определяет тонкую грань между использованием псевдонима и использованием функции. Когда псевдонимы становятся немного сложнее, обычно лучше написать функцию. При этом я нашел решение этого вопроса, которое позволяет расширять псевдонимы по желанию.
Я написал для этого функцию bash:
xtrace() {
local eval_cmd
printf -v eval_cmd '%q' "${@}"
{ set -x
eval "${eval_cmd}"
} 2>&1 | grep '^++'
return "${PIPESTATUS[0]}"
}
Флаг -v
printf
сохранит вывод printf
в указанной переменной.
В строке формата printf
%q
будет напечатан соответствующий аргумент (* в этом случае $@
) в кавычках , многократно используемый в качестве ввода. Это устраняет опасности, связанные с передачей произвольного кода / команд eval
.
Затем я использую группу команд { ... }
, чтобы я мог контролировать функциональность set -x
, которая сообщает bash для печати трассировки всех выполненных команд. Для моих целей мне не нужны никакие выходные данные, кроме полностью развернутой команды, поэтому я перенаправляю stderr
и grep
для строки вывода, которая начинается с "++". Это будет строка, которая показывает полностью развернутую команду.
Наконец, я возвращаю значение PIPESTATUS[0]
, которое содержит код возврата команды last , выполненной в группе команд (то есть команда eval
).
Таким образом, мы получим что-то вроде следующего:
$ xtrace la; echo $?
++ ls -G -aFhlT
0
Большое спасибо @CharlesDuffy за рекомендацию set -x
, а также входной санитарии для eval
.