Se você quiser passar um pipeline como git … | tar …
(é um único comando que contém dois subcomandos, não dois comandos separados) diretamente como um argumento para uma função, você precisará criar uma string contendo esse comando e usar o eval
embutido na função para executar essa string como um comando shell.
Cuide da cotação correta. Para o argumento, você está construindo uma string que é um script mini-shell usando as mesmas variáveis que o script anexo. Em particular, se uma variável contém um nome de arquivo (como tmp
here), você precisa passar a expansão de variável, não o valor da variável, porque um nome de arquivo não é um fragmento de shell, então você precisa de '…"$tmp"…'
, não "…$tmp…"
. Ao avaliar, você precisa passar a string exata para eval
, não uma string que já sofreu expansão. Em particular, $*
é praticamente sempre errado; leia Por que meu script de shell engasgar com espaço em branco ou outros caracteres especiais?
try () {
result=$(eval "$1" 2>&1)
if [ $? -ne 0 ]; then
failure
echo $result
exit 1
fi
success
}
try 'git archive --format=tar HEAD | tar xf - -C "$tmp"'
Uma abordagem alternativa é colocar o comando composto em uma função. Mais uma vez, cuide da cotação correta. Use "$@"
para avaliar os parâmetros da função como um comando simples (alias, função, comando interno ou externo com argumentos).
try () {
result=$(eval "$1" 2>&1)
if [ $? -ne 0 ]; then
failure
echo $result
exit 1
fi
success
}
archive_to_directory () {
git archive --format=tar HEAD | tar xf - -C "$1"'
}
try archive_to_directory "$tmp"
O status de um pipeline é o status do lado direito; o status do lado esquerdo é ignorado. No bash (mas não no sh), você pode acessar o status de todos os comandos em um pipeline através do PIPESTATUS
variable .
try () {
result=$(eval "$1" 2>&1)
if [ $? -ne 0 ]; then
failure
echo $result
exit 1
fi
success
}
archive_to_directory () {
git archive --format=tar HEAD | tar xf - -C "$1"'
[[ -n ${PIPESTATUS[*]//[0 ]/} ]]
}
try archive_to_directory "$tmp"