내 거세게 때리다스크립트 에는 실행할 수 있는 mysqldump blabla > dump.sql
많은 내용이 포함되어 있습니다.mysq balbla < dump.sql
시운전모델.
실제로 요점은 run
내가 요청하는 모든 것을 실행하는 함수를 만드는 것입니다.
run echo 'hello world'
run mysqldump blabla > dump.sql
run mysql blabla < dump.sql
run ssh blabla
# etc
run() {
if [[ "$(printenv DRY_RUN)" = "yes" ]]
then
echo "${@}"
else
${@}
fi
}
그러나 이것은 작동하지 않습니다.
run "mysqldump -uuser -ppass dbase > dump.sql"
다음 오류가 발생합니다.
mysqldump: 테이블을 찾을 수 없습니다: ">"
답변1
"${@}"
대신 ${@}
( with 와 같이 )을 사용해야 echo "${@}"
하지만 이것이 문제의 원인은 아닙니다.
그 이유는 매개변수 대체 전, 명령줄 구문 분석 초기에 리디렉션이 발생하기 때문입니다. 따라서 변수를 >
명령줄에 넣은 후에는 쉘이 더 이상 해당 변수를 찾지 않습니다 >
.
답변을 게시한 후 중요한 점을 발견했습니다. 이렇게 전화하면 됩니다.
run mysqldump blabla > dump.sql
함수는 합계를 run
볼 수 없습니다 . 의 출력 도 파일로 리디렉션되므로 단일 환경 변수를 사용하여 모든 리디렉션을 변경할 수 없으므로 이는 아마도 원하는 것이 아닐 것입니다 . 따라서 다음과 같은 것을 사용해야 합니다 . 아래를 참조하세요.>
dump.sql
echo "${@}"
run --redirect dump.sql mysqldump blabla
두 가지 가능성이 있습니다:
그것을 고수
"$@"
하고 사용하십시오eval
. 물론 이는 인용의 악몽으로 이어질 수 있습니다. 따옴표 제거를 수행하기 전에>
쉘이>
명령줄에서 기본 내용을 볼 수 있도록 를 제외한 모든 항목을 따옴표로 묶어야 합니다 .리디렉션을 개별적으로 처리합니다.
run --redirect dump.sql mysqldump blabla run() { if [ "$1" == '--redirect' ]; then shift redirect_target="$1" shift else redirect_target='/dev/stdout' # works at least with Linux fi if [[ "$(printenv DRY_RUN)" = "yes" ]] then echo "${@}" else "${@}" > "$redirect_target" fi }
redirect_target='/dev/stdout'
if [ "$1" == '--redirect' ]
의 분기에 배치하면 이를 피할 수 있습니다.else
if [[ "$(printenv DRY_RUN)" = "yes" ]]
if [[ "$(printenv DRY_RUN)" = "yes" ]] then if [ "$1" == '--redirect' ]; then # do not output "--redirect file" shift shift fi echo "${@}" else if [ "$1" == '--redirect' ]; then shift redirect_target="$1" shift "${@}" > "$redirect_target" else "${@}" fi fi
답변2
그림최근에 게시한 또 다른 답변, 토큰화가 리디렉션을 시작하기에는 너무 늦게 발생합니다(그러나 리디렉션에 영향을 주기에는 너무 늦지는 않습니다).
eval
연결된 게시물의 다른 답변에서 제안한 대로 run command 를 사용하거나 을 사용할 수 있지만 bash -c "$*"
여전히 전체 명령줄(리디렉션 포함)을 인용해야 합니다.
그러나 명령을 인용하지 않으려는 경우 한 가지 옵션은 bash가 명령을 실행하지 않고 인쇄만 하도록 -nv
( noexec
및 )를 설정하는 것입니다. verbose
따라서 run
래퍼를 사용하는 대신 스크립트 시작 부분에서 다음을 수행하세요.
[[ $DRY_RUN = yes ]] && set -nv
답변3
사용 "$@"
(큰따옴표 포함):
run() {
if [[ "$(printenv DRY_RUN)" = "yes" ]]
then
echo "${@}"
else
"$@"
fi
}
그것들이 없으면 $@
단일 태그로 확장됩니다.