Qual é a diferença entre o uso de; e executando um script

7

Estou usando bash como meu shell principal, mas é uma questão em aberto e as respostas para shells diferentes de bash são muito bem-vindas.

Se eu estiver digitando de forma interativa

#original line 
#wget http://something.com && unzip something && mv -f something /home/poney/ 
#new line
wget http://something.com ; unzip something ; mv -f something /home/poney/

Faz alguma diferença no termo de execução pilha, ordem, memória, interpretação, permissão comparar com um script que contém essa linha:

#!/bin/bash
wget http://something.com
unzip something 
mv -f something /home/poney/

PS:

exceto o fato de que executar um script é mais curto do que digitar o comando 3 em uma linha, obviamente.

    
por Kiwy 02.04.2014 / 11:42

3 respostas

17

Sim, há uma grande diferença. && é curto-circuito , então o comando subseqüente seria executado somente se o anterior retornasse com um código de saída 0 .

Citações do manual :

expression1 && expression2

True if both expression1 and expression2 are true.

Por outro lado, um script contendo

expression1
expression2

executaria a segunda expressão mesmo se a primeira falha. (A menos que você tenha especificado o script para sair com erro dizendo set -e .)

EDIT: Sobre o seu comentário se:

command1; command2

é o mesmo que:

command1
command2

A resposta é geralmente . Bash analisa um bloco inteiro de instrução antes de avaliar qualquer um deles. UMA ; não faz com que o comando anterior seja avaliado. Se o comando anterior tivesse um efeito sobre como o subsequente seria analisado, você notaria a diferença.

Considere um arquivo contendo aliases, vamos chamá-lo de alias , com uma entrada:

alias f="echo foo"

Agora, considere um script contendo:

shopt -s expand_aliases
source ./alias
f

e outro contendo:

shopt -s expand_aliases; source ./alias; f

então você pode pensar que ambos produziriam o mesmo resultado.

A resposta é NÃO. O primeiro produziria foo , mas o segundo reportaria:

... f: command not found

Para esclarecer ainda mais, não é expand_aliases que está causando o problema. O problema é devido ao fato de que uma declaração como:

alias f="echo foo"; f

seria analisado de uma só vez. O shell realmente não sabe o que é f , isso faz com que o analisador se sufoque.

    
por 02.04.2014 / 11:46
6

Sim, && é condição. O comando atrás só será iniciado se o anterior retornar 0 (termina sem um erro). Por outro lado, o seu script não tem esse controle, por exemplo, se. O wget termina com erro, ele continua e tenta descompactar e mover nada ..

O onliner para o seu script é:

wget http://something.com ; unzip something ; mv -f something /home/poney/
    
por 02.04.2014 / 11:49
2

Outra diferença para o mencionado é que seu script de shell é executado em um shell separado, portanto, quaisquer alterações no ambiente não serão propagadas. Por exemplo, se você digitar seu shell interativo

test -f foo && file=foo || file=other

o seu shell interativo conterá uma variável file (que você pode ler com $file ) contendo foo se o arquivo foo existir e for um arquivo normal e other caso contrário. Agora, se você colocar o mesmo em um script de shell e chamá-lo de seu shell interativo, a variável file no seu shell interativo não será definida (mas, é claro, dentro do seu shell script será definido, para que você possa usá-lo em outros comandos).

    
por 02.04.2014 / 11:59