Os três fragmentos de shell a seguir são equivalentes (como em, eles realizam a mesma coisa e você precisa cavar para observar qualquer efeito diferente):
env COLUMNS=%s ps …
COLUMNS=%s ps …
(export COLUMNS=%s; ps …)
Todos eles definem a variável de ambiente COLUMNS para o valor %s para a invocação do comando ps . No shell, o valor de COLUMNS , se houver, permanece o mesmo de antes. O primeiro fragmento realiza esse efeito através do programa externo env , o segundo usando a sintaxe do shell puro, o terceiro através do shell export integrado combinado com a construção do subconjunto (…) .
Isso é diferente de
export COLUMNS=%s; ps …
que definiria a variável de ambiente COLUMNS de uma maneira que permaneceria em vigor no restante do script e de
COLUMNS=%s; ps …
que, ao contrário dos outros, define apenas uma variável de shell (que ps não verá), mas não exporta COLUMNS para o ambiente. (No entanto, se COLUMNS já estiver presente no ambiente, ele será definido como %s .)
O programa env pode parecer inútil, mas existe
- porque é mais antigo que a construção
VAR=value command shell;
- porque é útil em outros casos, por exemplo, quando um programa inicia outro programa sem passar por um shell e você deseja definir algumas variáveis de ambiente;
- porque pode trabalhar com sistemas que tenham um shell diferente (por exemplo, em csh ou no Windows), desde que o comando
env esteja disponível e no PATH.
Todas as construções mencionadas aqui funcionam em qualquer shell do tipo Bourne / POSIX (sh, ash, bash, ksh, zsh,…), exceto algumas versões antigas do shell Bourne que você provavelmente nunca encontrará (e que nunca foi portado para Linux ou OSX).
Observe que COLUMNS deve ser um número; ps ignora se não for numérico. Zsh ainda se recusa a definir COLUMNS para um valor não numérico, porque ele declara COLUMNS como uma variável numérica por padrão. No programa que você está citando, %s será substituído por um número antes que a string seja usada como um comando shell.