Это не тривиальная проблема. Оболочка выполняет удаление кавычек перед вызовом функции, поэтому функция никак не может воссоздать кавычки в точности так, как вы их напечатали.
Однако, если вы просто хотите распечатать строку, которую можно скопировать и вставить, чтобы повторить команду, вы можете воспользоваться двумя различными способами:
- Создайте командную строку для запуска
eval
и передайте эту строкуdry_run
dry_run
Перед печатью укажите специальные символы команды
С помощью eval
Вот как вы можете использовать eval
для печати именно то, что выполняется:
dry_run() {
printf '%s\n' "$1"
[ -z "${DRY_RUN}" ] || return 0
eval "$1"
}
email_admin() {
echo " Emailing admin"
dry_run 'su - '"$target_username"' -c "cd '"$GIT_WORK_TREE"' && git log -1 -p|mail -s '"'$mail_subject'"' '"$admin_email"'"'
echo " Emailed"
}
Вывод:
su - webuser1 -c "cd /home/webuser1/public_html && git log -1 -p|mail -s 'Git deployment on webuser1' user@domain.com"
Обратите внимание на сумасшедшее количество цитат - у вас есть команда внутри команды, которая быстро становится ужасной. Осторожно: приведенный выше код будет иметь проблемы, если ваши переменные содержат пробелы или специальные символы (например, кавычки).
Цитирование специальных символов
Этот подход позволяет вам писать код более естественно, но людям труднее его читать, потому что shell_quote
реализован быстрый и грязный способ :
# This function prints each argument wrapped in single quotes
# (separated by spaces). Any single quotes embedded in the
# arguments are escaped.
#
shell_quote() {
# run in a subshell to protect the caller's environment
(
sep=''
for arg in "$@"; do
sqesc=$(printf '%s\n' "${arg}" | sed -e "s/'/'\\\\''/g")
printf '%s' "${sep}'${sqesc}'"
sep=' '
done
)
}
dry_run() {
printf '%s\n' "$(shell_quote "$@")"
[ -z "${DRY_RUN}" ] || return 0
"$@"
}
email_admin() {
echo " Emailing admin"
dry_run su - "${target_username}" -c "cd $GIT_WORK_TREE && git log -1 -p|mail -s '$mail_subject' $admin_email"
echo " Emailed"
}
Вывод:
'su' '-' 'webuser1' '-c' 'cd /home/webuser1/public_html && git log -1 -p|mail -s '\''Git deployment on webuser1'\'' user@domain.com'
Вы можете улучшить читабельность вывода, изменив shell_quote
специальные символы на обратную косую черту вместо того, чтобы заключать все в одинарные кавычки, но это трудно сделать правильно.
Если вы используете shell_quote
подход, вы можете su
создать команду для более безопасной передачи . Следующее будет работать, даже если ${GIT_WORK_TREE}
, ${mail_subject}
или ${admin_email}
содержит специальные символы (одинарные кавычки, пробелы, звездочки, точки с запятой и т. Д.):
email_admin() {
echo " Emailing admin"
cmd=$(
shell_quote cd "${GIT_WORK_TREE}"
printf '%s' ' && git log -1 -p | '
shell_quote mail -s "${mail_subject}" "${admin_email}"
)
dry_run su - "${target_username}" -c "${cmd}"
echo " Emailed"
}
Вывод:
'su' '-' 'webuser1' '-c' ''\''cd'\'' '\''/home/webuser1/public_html'\'' && git log -1 -p | '\''mail'\'' '\''-s'\'' '\''Git deployment on webuser1'\'' '\''user@domain.com'\'''