Respostas:
`date` será expandido apenas para a saída do date
comando. No entanto, ele remove caracteres de espaço extra em locais onde há mais de um caractere de espaço consecutivo na saída. (Isso ocorre porque a substituição do comando está sujeita à divisão de palavras e devido à maneira como o echo
comando lida com vários argumentos.)
Em "` date` " , as aspas duplas são aspas fracas; portanto, elas expandem variáveis (tente" $ PWD ") e executam a substituição de comandos. O resultado da expansão é passado como um único argumento para o echo
comando, com espaços consecutivos incluídos: ou seja, a divisão de palavras não é executada.
Em `` data '' , as aspas simples são aspas mais fortes, portanto, não permitirão a expansão de variáveis ou a substituição de comandos dentro delas.
Consulte este link para obter mais explicações.
Editou o primeiro ponto como apontado corretamente por Michael Suelmann no comentário abaixo .
date
comando bare .
Ambos
echo `date`
e
echo "`date`"
exibirá a data. A saída deste último parece com a saída sendo executada date
por si só.
Porém, há uma diferença: a pessoa entre "
aspas "
será enviada para echo
como um único argumento. As aspas encapsulam a saída de todo o comando como um argumento. Como echo
apenas imprime seus argumentos em ordem, com espaços no meio, basicamente parecerá o mesmo.
Aqui está um exemplo da diferença sutil:
echo `date`
produz:
Fri Nov 1 01:48:45 EST 2013
mas:
echo "`date`"
produz:
Fri Nov 1 01:48:49 EST 2013
Observe que os dois espaços seguintes Nov
foram reduzidos a um sem as aspas. Isso ocorre porque o shell está analisando cada elemento separado por espaço e enviando o resultado para ecoar como 6 argumentos. Quando você cita, o eco recebe um único argumento e as aspas retêm o espaço.
Isso se torna muito mais importante em comandos que não sejam eco. Por exemplo, imagine um comando foo
que queira dois argumentos: uma data e um endereço de email.
Isso funcionará nesse cenário:
foo "`date`" joeuser@example.com
Mas isso confundirá o script enviando-o 7 argumentos:
foo `date` joeuser@example.com
Nos shells POSIX, `date`
é a forma antiga de substituição de comando. A sintaxe moderna é $(date)
.
Nos dois casos, eles se expandem para a saída date
com os caracteres de nova linha à direita removidos (desde que a saída não contenha caracteres NUL).
No entanto, quando não estiver entre aspas duplas e em contextos de lista (por exemplo, em argumentos para comandos simples, como echo
no seu caso), essa expansão estará sujeita a:
Divisão de palavras : ou seja, a "saída de date
com os caracteres de nova linha à direita removidos" é dividida de acordo com o valor atual da $IFS
variável (por padrão, contendo espaço, tabulação e nova linha (e NUL com zsh
)) em várias palavras .
Por exemplo, se date
as saídas Fri 1 Nov 14:11:15 GMT 2013\n
(como costuma acontecer em um local Inglês e em um fuso horário britânico continente), e $IFS
atualmente contém :
, que será dividido em 3 palavras : Fri 1 Nov 14
, 11
e 15 GMT 2013
.
zsh
): isto é, cada palavra resultante da divisão acima é procurado caracteres curinga ( *
, ?
, [...]
embora algumas conchas têm mais), e expandiu-se para a lista de nomes de arquivos que correspondem a esses padrões. Por exemplo, se a saída date
é ?%? 33 */*/* UVC 3432
(como muitas vezes é em locais venusianos e fuso horário UVC), e $IFS
é o valor padrão), em seguida, que se expande para todos os não-escondida 3 nomes de personagens no diretório atual cujo personagem central é %
, 33
, todos os arquivos não ocultos em todos os subdiretórios não ocultos de todos os subdiretórios não ocultos do diretório atual UVC
e 3432
.É por isso que:
$IFS
os caracteres nos quais deseja dividir.set +f
para desativá-lo.As aspas simples citam tudo, fazendo com que os caracteres do backtick sejam interpretados literalmente.
Exemplo (o uso -x
facilita a visualização do que está acontecendo):
$ bash --norc -x
bash-4.2$ IFS=:
+ IFS=:
bash-4.2$ echo `date`
++ date
+ echo 'Fri 1 Nov 14' 42 '33 GMT 2013'
Fri 1 Nov 14 42 33 GMT 2013
bash-4.2$ echo "`date`"
++ date
+ echo 'Fri 1 Nov 14:42:41 GMT 2013'
Fri 1 Nov 14:42:41 GMT 2013
bash-4.2$ cd /lib/modules
+ cd /lib/modules
bash-4.2$ export TZ=UVC LC_ALL=vs_VS
+ export TZ=UVC LC_ALL=vs_VS
+ TZ=UVC
+ LC_ALL=vs_VS
bash-4.2$ unset -v IFS # get the default behaviour
+ unset -v IFS
bash-4.2$ echo `date`
++ date
+ echo '?%?' 33 3.10-2-amd64/build/arch 3.10-2-amd64/build/include 3.10-2-amd64/build/Makefile 3.10-2-amd64/build/Module.symvers 3.10-2-amd64/build/scripts 3.10-2-amd64/kernel/arch 3.10-2-amd64/kernel/crypto 3.10-2-amd64/kernel/drivers 3.10-2-amd64/kernel/fs 3.10-2-amd64/kernel/lib 3.10-2-amd64/kernel/mm 3.10-2-amd64/kernel/net 3.10-2-amd64/kernel/sound 3.10-2-amd64/source/arch 3.10-2-amd64/source/include 3.10-2-amd64/source/Makefile 3.10-2-amd64/source/scripts 3.10-2-amd64/updates/dkms 3.10-3-amd64/build/arch 3.10-3-amd64/build/include 3.10-3-amd64/build/Makefile 3.10-3-amd64/build/Module.symvers 3.10-3-amd64/build/scripts 3.10-3-amd64/kernel/arch 3.10-3-amd64/kernel/crypto 3.10-3-amd64/kernel/drivers 3.10-3-amd64/kernel/fs 3.10-3-amd64/kernel/lib 3.10-3-amd64/kernel/mm 3.10-3-amd64/kernel/net 3.10-3-amd64/kernel/sound 3.10-3-amd64/source/arch 3.10-3-amd64/source/include 3.10-3-amd64/source/Makefile 3.10-3-amd64/source/scripts 3.10-3-amd64/updates/dkms UVC 3432
?%? 33 3.10-2-amd64/build/arch 3.10-2-amd64/build/include 3.10-2-amd64/build/Makefile 3.10-2-amd64/build/Module.symvers 3.10-2-amd64/build/scripts 3.10-2-amd64/kernel/arch 3.10-2-amd64/kernel/crypto 3.10-2-amd64/kernel/drivers 3.10-2-amd64/kernel/fs 3.10-2-amd64/kernel/lib 3.10-2-amd64/kernel/mm 3.10-2-amd64/kernel/net 3.10-2-amd64/kernel/sound 3.10-2-amd64/source/arch 3.10-2-amd64/source/include 3.10-2-amd64/source/Makefile 3.10-2-amd64/source/scripts 3.10-2-amd64/updates/dkms 3.10-3-amd64/build/arch 3.10-3-amd64/build/include 3.10-3-amd64/build/Makefile 3.10-3-amd64/build/Module.symvers 3.10-3-amd64/build/scripts 3.10-3-amd64/kernel/arch 3.10-3-amd64/kernel/crypto 3.10-3-amd64/kernel/drivers 3.10-3-amd64/kernel/fs 3.10-3-amd64/kernel/lib 3.10-3-amd64/kernel/mm 3.10-3-amd64/kernel/net 3.10-3-amd64/kernel/sound 3.10-3-amd64/source/arch 3.10-3-amd64/source/include 3.10-3-amd64/source/Makefile 3.10-3-amd64/source/scripts 3.10-3-amd64/updates/dkms UVC 3432
bash-4.2$ echo "`date`"
++ date
+ echo '?%? 33 */*/* UVC 3432'
?%? 33 */*/* UVC 3432
Se a saída contiver caracteres NUL, o comportamento varia de shell para shell: alguns os removem, outros truncam a saída no primeiro caractere NUL, zsh
preservam-nos, mas observe que de qualquer maneira os comandos externos não podem aceitar argumentos que contenham NULs
Com `date ', você obtém a saída da data dividida em várias palavras, porque a divisão da palavra é feita após a substituição do comando.
Com "` date` ", você obtém a saída da data como uma palavra / parâmetro, pois há substituição de comando entre aspas duplas, mas a saída não é mais analisada. O mesmo é válido com expansão variável como "$ i" no meu exemplo abaixo.
Com '`date' ', você obtém uma` date' literal, pois não há substituição de comando entre aspas simples.
Talvez as diferenças das três formas sejam mais visíveis desta maneira:
> for i in `date`; do echo "$i"; done
Fr
1.
Nov
12:25:30
CET
2013
> for i in "`date`"; do echo "$i"; done
Fr 1. Nov 12:25:38 CET 2013
> for i in '`date`'; do echo "$i"; done
`date`