Creo que --includese utiliza para incluir un subconjunto de archivos que de otro modo están excluidos por --exclude, en lugar de incluir solo esos archivos. En otras palabras: tienes que pensar en incluir el significado de no excluir .
Prueba en su lugar:
rsync -zarv --include "*/" --exclude="*" --include="*.sh" "$from" "$to"
Para rsync versión 3.0.6 o superior, el orden debe modificarse de la siguiente manera (ver comentarios):
rsync -zarv --include="*/" --include="*.sh" --exclude="*" "$from" "$to"
Agregar la -mbandera evitará crear estructuras de directorio vacías en el destino. Probado en la versión 3.1.2.
Entonces, si solo queremos archivos * .sh, tenemos que excluir todos los archivos --exclude="*", incluir todos los directorios --include="*/"e incluir todos los archivos * .sh --include="*.sh".
Puede encontrar algunos buenos ejemplos en la sección Incluir / excluir reglas de patrón de la página de manual