Há duas maneiras de capturar a saída da linha de comando bash
:
Backticks de shell Bourne herdados
``
:var=`command`
$()
sintaxe (que, tanto quanto eu sei, é específica do Bash, ou pelo menos não é suportada por shells antigos não POSIX como o Bourne original)var=$(command)
Existe algum benefício em usar a segunda sintaxe em comparação com os backticks? Ou os dois são totalmente 100% equivalentes?
$()
é POSIX e é suportado por todos os shells Bourne modernos, por exemplo, ksh, bash, ash, dash, zsh, busybox, você escolhe. (Um não tão moderno é o Solaris/bin/sh
, mas no Solaris você deve usar o moderno/usr/xpg4/bin/sh
).$()
e backticks em aliases. Se você tiver oalias foo=$(command)
seu.bashrc
,command
será executado quando o próprio comando alias for executado durante a.bashrc
interpretação. Comalias foo=`command`
,command
será executado sempre que o alias for executado. Mas se você escapar do$
com o$()
formulário (por exemploalias foo=\$(command)
), ele também será executado toda vez que o alias for executado, em vez de durante a.bashrc
interpretação. Tanto quanto eu posso dizer por testes, de qualquer maneira; Não consigo encontrar nada nos documentos do bash que expliquem esse comportamento.`command`
command
é executado apenas uma vez. Eu verifiquei: function aaa () {printf date; eco aaa >> ~ / test.txt; } alias test1 =aaa
. A função aaa está executando apenas uma vez (após cada login), não importa quantas vezes o alias (test1
) foi executado. Eu usei .bashrc (no Debian 10).Respostas:
O principal é a capacidade de aninhar os comandos dentro de comandos, sem perder sua sanidade mental, tentando descobrir se alguma forma de fuga funcionará nos retângulos.
Um exemplo, embora um tanto artificial:
que fornecerá uma lista de todos os arquivos na
/dir
árvore de diretórios com o mesmo nome do arquivo de texto com data mais antiga de dezembro de 2011 (a) .Outro exemplo seria algo como obter o nome (não o caminho completo) do diretório pai:
(a) Agora que esse comando específico pode não funcionar realmente, não testei a funcionalidade. Portanto, se você me rejeita, perde de vista a intenção :-) É apenas uma ilustração de como você pode aninhar, não como um trecho pronto para a produção sem erros.
fonte
Do whatever the heck you want with it.
" :-) De qualquer forma, tenho certeza de que foi humor do DVK.Suponha que você queira encontrar o diretório lib correspondente a onde
gcc
está instalado. Você tem uma escolha:O primeiro é mais fácil que o segundo - use o primeiro.
fonte
x=$(f); x=`f`
se comportam da mesma forma quex="$(f)"; x="`f`"
. Em contraste, a atribuição de matrizx=($(f)); x=(`f`)
fazer executar divisão em$IFS
caracteres como esperado quando invocando comandos. Isso é conveniente (x=1 2 3 4
não faz sentido), mas inconsistente.x=$(f)
trabalho sem aspas. Eu deveria ter sido mais específico; Eu estava propondo usarlibdir=$(dirname "$(dirname "$(which gcc)")")/lib
(aspas em torno das substituições de comandos internos ). Se não for indicado, você ainda estará sujeito à divisão usual da palavra e à expansão glob.Os backticks (
`...`
) são a sintaxe herdada exigida apenas pelos bourne-shells mais antigos e não compatíveis com$(...)
POSIX, sendo POSIX e mais preferido por vários motivos:As barras invertidas (
\
) dentro dos backticks são tratadas de maneira não óbvia:A citação aninhada no interior
$()
é muito mais conveniente:ao invés de:
ou escrevendo algo como:
Porque
$()
usa um contexto totalmente novo para citaro que não é portátil, pois as conchas de Bourne e Korn exigiriam essas barras invertidas, enquanto Bash e dash não.
A sintaxe para aninhar substituições de comandos é mais fácil:
do que:
Porque
$()
impõe um contexto inteiramente novo para citação, cada substituição de comando é protegida e pode ser tratada por si só, sem preocupação especial com a citação e escape. Ao usar as costas, fica cada vez mais feio depois de dois e acima dos níveis.Mais alguns exemplos:
Ele resolve um problema de comportamento inconsistente ao usar aspas:
echo '\$x'
saídas\$x
echo `echo '\$x'`
saídas$x
echo $(echo '\$x')
saídas\$x
A sintaxe dos backticks possui restrições históricas no conteúdo do comando incorporado e não pode manipular alguns scripts válidos que incluem aspas, enquanto o
$()
formulário mais recente pode processar qualquer tipo de script incorporado válido.Por exemplo, esses scripts incorporados válidos de outra forma não funcionam na coluna da esquerda, mas no IEEE da direita :
Portanto, a sintaxe da substituição de comando
$
pré-prefixada deve ser o método preferido, porque é visualmente clara com sintaxe limpa (melhora a legibilidade humana e da máquina), é aninhada e intuitiva, sua análise interna é separada e também é mais consistente (com todas as outras expansões analisadas entre aspas duplas), onde os backticks são a única exceção e o caractere é facilmente camuflado quando adjacente a`
"
tornando a leitura ainda mais difícil, especialmente com fontes pequenas ou incomuns.Fonte: Por que o
$(...)
preferido é sobre`...`
(backticks)?no BashFAQVeja também:
fonte
De man bash:
fonte
Além das outras respostas,
se destaca visualmente melhor do que
Backticks parecem muito com apóstrofos; isso varia dependendo da fonte que você está usando.
(E, como acabei de notar, os backticks são muito mais difíceis de inserir em exemplos de código embutido.)
fonte
$
(
e)
do que para backtick; YMMV.$()
permite o aninhamento.Eu acho que backticks não permite isso.
fonte
out=`echo today is \`date\``
.É o padrão POSIX que define a
$(command)
forma de substituição de comando. A maioria dos shells em uso atualmente são compatíveis com POSIX e suportam essa forma preferida em relação à notação arcaica de backtick. A seção de substituição de comando (2.6.3) do documento Shell Language descreve isso:fonte
Esta é uma pergunta legada, mas eu vim com um exemplo perfeitamente válido de
$(...)
mais`...`
.Eu estava usando uma área de trabalho remota no Windows executando o cygwin e queria iterar sobre o resultado de um comando. Infelizmente, era impossível inserir o caractere backtick, devido à área de trabalho remota ou ao próprio cygwin.
É sensato supor que um cifrão e parênteses serão mais fáceis de digitar em configurações tão estranhas.
fonte