Seu comando run
provavelmente espera que um comando seja executado em oposição ao código shell a ser avaliado (edite agora que você o publicou: sim, isso é "$@"
)
Se o comando run
for realmente um script de shell, ele poderá aceitar comandos internos como eval
(editar: sim, funciona), caso em que você deve ser capaz de fazer:
./run eval 'git status && npm install'
(esse código seria avaliado no contexto do script run
, que poderia ter efeitos inesperados se modificasse algumas variáveis internas do script, por exemplo (como ./run eval 'PATH=/none; ...'
) (editar: não aqui, pois é o último comando) executado em um subshell)).
Se não, você sempre pode dizer para executar um shell para avaliar o código do shell:
./run sh -c 'git status && npm install'
Aqui, eu também usaria uma variável array para armazenar uma lista de caminhos ao invés de armazená-la em uma variável escalar e contar com o operador split + glob para dividi-la. Você também pode querer relatar falhas no status de saída
#!/bin/bash -
paths=(/Users/guy/project /Users/guy/project-2)
ret=0
for i in "${paths[@]}"; do
(cd -P -- "$i" && "$@") || ret=$?
done
exit "$ret"
Se você quisesse que seu script aceitasse o código shell, você faria:
#!/bin/bash -
paths=(/Users/guy/project /Users/guy/project-2)
ret=0
for i in "${paths[@]}"; do
(cd -P -- "$i" && eval "$@") || ret=$?
done
exit "$ret"
Mas aconselho a não fazê-lo, pois o usuário pode ficar tentado a fazer coisas como:
./run git add "$file"
que seria uma vulnerabilidade de injeção de comando oculta (como quando $file
é foo;reboot
).
./run eval "git add $file"
seria a mesma vulnerabilidade de injeção de comando, mas pelo menos não estaria oculta para o usuário.
Para que não seja uma vulnerabilidade de injeção de comando, com a variante de run
não usando eval
:
./run git add "$file"
ou usando eval
, mas com código estático e passando o valor dinâmico por meio de uma variável de ambiente.
FILE=$file ./run eval 'git add "$FILE" && git commit -m blah'
ou usando sh -c
, mas com código estático e passando o valor dinâmico por meio de um argumento.
./run sh -c 'git add "$1" && git commit -m blah' sh "$file"