Como o script a seguir pode ser explicado?

1

Código:

#!/bin/csh

if ( A$1 == A ) then
    echo ""
    echo "LIST <name>"
    echo ""
    exit
endif

..............

Ok, esta é uma amostra de um script maior que recebi. Os scripts começam com este pedaço de código e não estão relacionados a nenhum dos códigos que seguem depois.

O uso do script é como: LIST 'name' , em que LIST é o comando de script e 'name' é uma constante constante introduzida pelo usuário.

O que eu sei até agora é que se eu executar o script assim:

LIST 'name'

o script fará o trabalho com a constante 'name' mas se eu correr sem 'name' assim:

LIST

mostrará:

LIST <name>

como uma breve descrição de como usar o comando. Esta descrição é do eco dentro se.

O que preciso entender é o que esta linha faz:

if ( A$1 == A ) then

Obrigado!

    
por Futur'Fusionneur 28.08.2014 / 16:52

4 respostas

4

Isso garante que $1 não seja uma string vazia. Se $1 for string vazia, se a condição for:

( A == A )

avaliado como verdadeiro. Este é um trabalho para garantir que você não tenha um erro de sintaxe. Se você simplesmente fizer:

if ( $1 == "" )

Quando $1 é string vazia, esta expressão se torna ( == "" ) causa um erro de sintaxe.

Pelo menos em bsd-csh , tcsh , ( $1 == "" ) funciona. Com o original csh , você deve usar:

if ( "A$1" == "A" )

Uma observação de que você deve sempre aspas duplas de sua variável, consulte a explicação aqui . Em csh , se a variável $a contiver nova linha, então "$a" não funcionará, você precisará de $a:q .

    
por 28.08.2014 / 17:04
0

Esta linha verifica se $1 está vazio. $1 é o primeiro parâmetro passado ao script pelo usuário ao executar o script na linha de comando. Se $1 estiver vazio, nada será anexado à letra A e A == A é verdadeiro.

    
por 28.08.2014 / 17:02
0

Eu acredito que o loop if é usado como uma maneira de testar se os argumentos são passados ou não para o script. Embora tecnicamente seja o propósito do loop if , acho que seria mais apropriado dizer que ele é usado para verificar se o $1 está vazio ou não. Por exemplo, copiei o script e o invoquei como

script "some_argument"

Como esperado, ele não entra no loop if . Agora, se eu invoco isso sem nenhum parâmetro,

script

Eu recebo a saída como LIST <name>

Então, adicionei uma instrução echo antes do loop if para verificar os argumentos passados para o script. Então, se invoco o script sem nenhum argumento, ele entra no loop if .

Além disso, A$1 == A é apenas algo para testar se $ 1 estiver vazio ou não. Mesmo se você tiver algo como somethingvalid$1 == somethingvalid e invocar o script como script , ele ainda entrará no loop if e imprimirá a saída.

    
por 28.08.2014 / 17:00
0

O Gnouc faz um ponto importante sem enfatizá-lo: sempre que você fizer referência a uma variável de shell ( $identifier , por exemplo, $futur ) ou um parâmetro posicional ( $digit , por exemplo, $1 ), você deve colocá-lo entre aspas duplas (por exemplo, "$1" ), a menos que você tenha um bom motivo para não e você tem certeza de que sabe o que está fazendo. Sequências constantes sem caracteres especiais (por exemplo, A , foo ou bar ) não precisa ser citado, mas não dói. As strings entre aspas podem ser concatenadas e combinadas; por exemplo, "foo""bar" é equivalente a "foobar" , e A"$1" é equivalente a "A""$1" e, portanto, "A$1" .

  • As cotações preservam a existência de cadeias vazias. Como Gnouc explica, se seu roteiro dissesse

    if ( $1 == "" )
    

    e você invoca sem argumentos,

    LIST
    

    ou com um argumento de cadeia vazia explícito,

    LIST ""
    

    , a declaração if será "expandida" como

    if ( == "" )
    

    que causa um erro de sintaxe.

  • As cotações preservam a integridade das sequências com espaços ou caracteres especiais. Se você invocar seu script com um argumento contendo um espaço,

    LIST "foo bar"
    

    , a declaração if ( if ( A$1 == A ) ) será expandida como

    if ( Afoo bar == A )
    

    que causa um erro de sintaxe. Resultados semelhantes acontecem se você invocar seu script com um argumento contendo um caractere curinga entre aspas:

    LIST "foo*"
    

Mas ninguém explicou por que o roteiro não diz apenas

if ( "$1" == "" )

Nas versões anteriores de csh , se você invocar seu script com o argumento this ,

LIST ==

, a declaração if será expandida como

if ( "==" == "" )

que também causou um erro de sintaxe. As pessoas escreveram suas declarações if com proteção para parâmetros posicionais (e, quando apropriado, variáveis de shell / variáveis de ambiente), como A$1 ou "A$1" , para evitar que os argumentos (operandos) se pareçam com operadores (particularmente / , também + , - e * ) e fazendo com que o analisador seja confundido. Isso parece ter sido corrigido (pelo menos em algumas versões do csh / tcsh ). Eu apenas tentei isso na minha versão (do Cygwin) de tcsh :

$ if ( == == "" ) echo yes
if: Expression Syntax.
$ if ( == == == ) echo yes
if: Expression Syntax.
$ if ( "==" == "" ) echo yes
                                <--- (no output)
$ if ( "==" == "==" ) echo yes
yes
$ if ( / == / ) echo yes
Division by 0.
$ if ( "/" == "/" ) echo yes
yes

então,

  • As cotações podem informar o comando if em tcsh que um argumento é um operando e não um operador.
por 28.08.2014 / 19:19