Você pode salvar seus argumentos em uma matriz:
args=( "$@" ) # use double quotes
shift 1
if foo; then
node foo.js "$@"
elif bar; then
node bar.js "$@"
elif baz; then
node baz.js "$@"
else
node default.js "${args[@]}"
fi
Eu tenho este cenário
first_arg="$1";
if foo; then
shift 1;
node foo.js "$@"
elif bar; then
shift 1;
node bar.js "$@"
elif baz; then
shift 1;
node baz.js "$@"
else
node default.js "$@"
fi
Eu gostaria de transformar o texto acima em:
first_arg="$1";
shift 1;
if foo; then
node foo.js "$@"
elif bar; then
node bar.js "$@"
elif baz; then
node baz.js "$@"
else
unshift 1;
node default.js "$@"
fi
mas não tenho certeza se existe um operador como unshift, que acabei de inventar. Uma solução alternativa pode ser esta:
node default.js "$first_arg" "$@"
mas quando tentei isso, tive um comportamento estranho.
Você nunca precisa usar shift 1
em primeiro lugar. Basta usar os argumentos posicionais e dividir seus índices para passar os argumentos.
first_arg="$1"
Depois de fazer isso, o restante dos argumentos pode ser acessado como "${@:2}"
. A notação é uma maneira de representar do argumento posicional 2 até o final da lista.
Usar a construção para o seu exemplo seria fazer
node foo.js "${@:2}"
e para a parte final else
faça como
node default.js "$1" "${@:2}"
que é o mesmo que fazer "$@"
, pois não há mudança de argumento posicional.
A coisa que você tentou:
first_arg=$1
shift
# ...later...
else
node default.js "$first_arg" "$@"
fi
Isso seria idêntico à sua primeira variante, desde que haja pelo menos um argumento de linha de comando.
Sem argumentos de linha de comando "$first_arg"
ainda seria uma string vazia e, portanto, um argumento, enquanto "$@"
não geraria nem mesmo uma string vazia.
Se o seu aplicativo Node aceitar um argumento vazio na linha de comando, isso pode fazer com que o aplicativo se comporte diferente em suas duas variantes de código.
Se chamar seu script sem argumentos de linha de comando é uma coisa válida a fazer, você poderia fazer
node default.js ${first_arg:+"$first_arg"} "$@"
em que ${first_arg:+"$first_arg"}
seria expandido para nada se first_arg
estivesse vazio ou não definido, mas para "$first_arg"
if first_arg
definido como uma string não vazia. Ou, se você quiser causar uma falha explícita por uma variável não definida ou vazia:
node default.js "${first_arg:?Error, no command line arguments}" "$@"
Alternativas inclui fazer uma cópia de $@
como bash
array como Jesse_b mostra em sua resposta .
Colocar $first_arg
de volta em $@
com
set -- "$first_arg" "$@"'
não funcionaria, pois isso incluiria um argumento vazio como $1
in $@
se o argumento da linha de comando estivesse faltando.
com
set -- ${first_arg:+"$first_arg"} "$@"'
você "não mudaria" nada se $first_arg
estivesse vazio ou se a variável não existisse.
Note que shift é o mesmo que shift 1 e que instruções únicas não precisam ser terminadas por; a menos que seja seguido por outra instrução na mesma linha (newline é um terminador de comando, assim como;).