Você deve usar "${@}"
em vez de ${@}
(como com echo "${@}"
), mas essa não é a razão do seu problema.
O motivo é que o redirecionamento ocorre muito cedo na análise da linha de comando, antes da substituição do parâmetro. Assim, depois que a variável colocar >
na linha de comando, o shell não está mais procurando >
.
Um ponto importante que notei depois de publicar minha resposta: com uma chamada como
run mysqldump blabla > dump.sql
a função run
não vê >
e dump.sql
. Isso provavelmente não é o que você deseja porque impede que você altere todos os redirecionamentos com uma única variável de ambiente, já que a saída de echo "${@}"
é redirecionada para o arquivo também. Assim, você deve usar algo como run --redirect dump.sql mysqldump blabla
, veja abaixo.
Existem duas possibilidades:
-
Cole com
"$@"
e useeval
. Isso pode levá-lo a um pesadelo de citação, é claro. Você precisa citar tudo, exceto o>
, para que o shell veja um>
na linha de comando antes de fazer a remoção da cotação. -
Manipule o redirecionamento separadamente:
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 }
Você pode evitar o
redirect_target='/dev/stdout'
se você colocar oif [ "$1" == '--redirect' ]
na filialelse
deif [[ "$(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