Nel tuo primo esempio, stai dando -c
flag a docker exec
. Questa è una risposta facile:docker exec
non ha un -c
bandiera.
Nel tuo secondo esempio, la tua shell lo sta analizzando in due comandi prima ancora che Docker lo veda. È equivalente a questo:
if docker exec [id] cd /var/www/project
then
composer install
fi
Innanzitutto, il docker exec
viene eseguito e se esce da 0 (successo), composer install
cercherà di essere eseguito localmente , al di fuori di Docker.
Quello che devi fare è passare entrambi i comandi come singolo argomento a docker exec
utilizzando una stringa. Quindi non saranno interpretati da una shell finché non sono già all'interno del contenitore.
docker exec [id] "cd /var/www/project && composer install"
Tuttavia, come hai notato nei commenti, anche questo non funziona. Questo perché cd
è una shell incorporata e non esiste da sola. Il tentativo di eseguirlo come comando iniziale fallirà. Quindi il passo successivo è consegnarlo a una shell per l'esecuzione.
docker exec [id] "bash -c 'cd /var/www/project && composer install'"
E infine, a questo punto il &&
si è spostato in una serie interna di virgolette, quindi non abbiamo davvero bisogno delle virgolette intorno al bash
comando... puoi rilasciarli se preferisci.
docker exec [id] bash -c 'cd /var/www/project && composer install'
Tutto ciò che segue l'id del contenitore è il comando da eseguire, quindi nel primo esempio -c
non è un'opzione per exec, ma una finestra mobile di comando tenta di essere eseguita e fallisce poiché quel comando non esiste.
Molto probabilmente hai trovato questa sintassi da un docker run
comando in cui il punto di ingresso è stato impostato su /bin/sh
. Tuttavia, exec ignora il punto di ingresso, quindi è necessario includere il comando completo per l'esecuzione. Come altri hanno sottolineato, quel comando include una shell come bash o nell'esempio seguente, sh:
docker exec [id] /bin/sh -c 'cd /var/www/project && composer install'