Script de Shell> comillas dobles de un parámetro, SOLO si existe

Antecedentes: actualmente tenemos un proyecto, que requiere clonar múltiples repositorys de git en una sola carpeta principal. Intento escribir un script para poder ejecutar las operaciones de git en todos los subdirectorys, para que sea más fácil de administrar (por ejemplo, ./gitall.sh status / add / reset / commit -m "Foobar" / push / etc .

El script funciona bien para todas las operaciones, hasta que bash realizar un ./gitall.sh push

Recibo el error fatal: remote part of refspec is not a valid name in para cada directory, porque el command efectivo es git -C somedir push "" "" "" "" ( git borks en las comillas dobles finales). Nota: los parameters deben ser doblemente citados, de modo que capture parameters con espacios.

gitall.sh

 find ./repo-* -type d -depth 0 -exec bash -c "git -C {} \"$1\" \"$2\" \"$3\" \"$4\" \"$5\"" \; 

¿Hay alguna forma de duplicar un parámetro, SÓLO si existe? (¿o de todos modos para decirle a git que ignore las comillas dobles finales?)

El problema es que estás pasando arguments adicionales a git push . Cada "" es pasado por el intérprete de commands a git que luego piensa que obtiene 7 arguments, pero los últimos 4 son cadenas vacías.

Lo que estás buscando es "$@" . "$@" es equivalente a "$1" "$2" ...

No hay necesidad de todas las cotizaciones adicionales, ni la bash -c . "$@" se expandirá en el script de shell.

También tenga en count que la invocación de find no funcionará con GNU find, así que utilice la ruta completa de BSD find.

 #/bin/sh /usr/bin/find ./repo-* -type d -depth 0 -exec git -C {} "$@" \; 

La forma correcta de pasar un número desconocido de parameters en bash es usar "$@" . Además, no necesita llamar explícitamente a bash , porque complicará la forma en que necesita citar los parameters.

Esto citará automáticamente todos los parameters:

 #!/bin/bash find ./repo-* -type d -depth 0 -exec git -C {} "$@" ';' 

Yendo un paso más, no hay necesidad de llamar a find si todo lo que quiere son inputs de directory en el nivel actual. El / al final del patrón de coincidencia seleccionará solo directorys:

 #!/bin/bash for d in repo-*/; do [ -d "$d" ] && git -C "$d" "$@" done 

(Tenga en count que si no tiene ningún directory que coincida con el patrón, el ciclo se ejecutará una vez con el argumento literal repo-*/ ; el [ -d "$d" ] evitará que se llame a git en este caso).

Por último, es posible que desee considerar el uso de la herramienta repo de Google en lugar de su propia solución para administrar múltiples repositorys git. Es muy poderoso y fácil de usar.

Lo que busca es "$@" , y hay mejores forms de hacer lo que hace:

 find -name .git -prune -execdir git "$@" \; 

y puede agregar -maxdepth 1 o lo que sea para limitar aún más la -maxdepth 1 del command de búsqueda.