script bash

script bash

Estou lendo o script bash e não entendo o que está acontecendo lá.

#!/bin/sh
[ x$1 = x ] 

O que está acontecendo na segunda linha e o que [ x$1 = x ] significa?

Responder1

Isso verifica se $1está vazio, embora deva estar entre aspas (idêntico a [ -z "$1" ]). Alguns shells muito antigos não lidavam com strings vazias adequadamente, então os escritores de scripts portáteis adotaram esse estilo de verificação. Não é necessário há décadas, mas as pessoas ainda fazem assim porque ainda fazem assim.

Responder2

Colchetes indicam umteste, portanto, [ x$1 = x]sem ifou algo semelhante não tem sentido, embora sintaticamente ok.

O objetivo é avaliar como verdadeiro se for x$1expandido para xe falso caso contrário, mas como não está entre aspas, se $1for (por exemplo) "ei x", o shell verá x = x, portanto, essa construção ainda não é segura.

O objetivo da x = xverificação é determinar se uma variável está vazia. Uma maneira mais comum de fazer isso seria apenas usar aspas:

if [ "$1" = "" ]; then

Operadores de teste Bash -ztambém -npodem ser usados, mas são menos portáveis ​​para outros tipos de shells. 1

O motivo das aspas, ou x$1, é para que o lado esquerdo não se expanda para nada, o que seria um erro sintático:

if [  = x ]  # No good!
if [ "" =  "" ] # Okay.
if [ x = x ] # Also okay.

1. Na verdade, testpode ser um utilitário independente, mas a maioria dos shells o implementa como um utilitário integrado; verifique a diferença entre which teste type test. No GNU/Linux man testafirma se referir ao integrado, mas se você chamar (por exemplo) /usr/bin/test, esse utilitário parece implementar os recursos documentados na página de manual, incluindo -ze -n.

Responder3

[ x$1 = x ]

Só faz sentido em zsh. Isso compara a concatenação de xcom o primeiro argumento do script para x. Portanto, o [comando retorna verdadeiro se $1estiver vazio ou não for fornecido.

[ $1 = "" ]

Não funcionaria porque, quando zshuma variável vazia não é citada em contextos de lista, ela se expande para nenhum argumento em vez de um argumento vazio, portanto, se $1não estivesse definido ou vazio, o [comando receberia apenas como argumentos [, =, a string vazia e ]do qual não fazia sentido. [ -z "$1" ]ou [ "$1" = "" ]seria bom, como nos shells POSIX.

Em shells tipo Bourne/POSIX, [ x$1 = x ]não faz sentido. Esse é o operador split+glob aplicado de alguma forma à concatenação de xe ao primeiro argumento do script, esperando que o resultado and =e xconstitua ]uma expressão de teste válida para o [comando.

Por exemplo, se o script recebesse um " = x -o x ="argumento, [receberia esses argumentos: [, x, =, x, -o, x, =, x, ], que [seria entendido como comparação xcom xe xcom xe retornaria verdadeiro.

Se $1fosse "* *", então o shell passaria para o [comando a lista de arquivos no diretório atual cujo nome começa com x(a expansão glob de x*), depois a lista de arquivos não ocultos (expansão *)... o que [é improvável que seja capaz para fazer algum sentido. Os únicos casos em que isso faria algo sensato é se $1não contiver caracteres curinga ou caracteres em branco.

Agora, o que você às vezes encontra é um código como:

[ "x$1" = x ]

Isso é usado para testar se $1está vazio ou não definido.

A maneira normal de testar uma variável vazia ou não definida é:

[ -z "$1" ]

Mas isso falha para alguns valores $1como =em algumas implementações (não POSIX), [como a incorporada no shell Bourne, encontrada /bin/shno Solaris 10 e anteriores ou em algumas versões antigas dash(até 0.5.4) ou de shalguns BSDs.

Isso porque [[, -z, =e ]reclama da falta de argumentos no =operador binário em vez de entendê-lo como o -zoperador unário aplicado à =string.

Da mesma forma, [ "$1" = "" ]falha em algumas implementações de [if $1is !ou (.

Nessas [implementações shell/:

[ "x$1" = x ]

é sempre um teste válido, independentemente do valor de $1, assim como:

[ "" = "$1" ]

e:

[ -z "${1:+x}" ]

e

case $1 in "") ...; esac

Claro, se você quiser verificar se nenhum argumento foi fornecido, você faria:

[ "$#" -eq 0 ]

Ou seja, você verifica a quantidade de argumentos passados ​​para o script.

Observe que hoje em dia, [ -z "$var" ]é claramente especificado pelo POSIX e não pode falhar em [implementações compatíveis (e bashé [e tem sido há décadas). Portanto, você deve poder confiar nele em sh ou bashscripts POSIX.

Responder4

[ x$1 = x ]é verdadeiro se $1não estiver definido/nulo/vazio ou não.
Experimente você mesmo com:
TEST= ;[ x$TEST = x] && echo "TEST is unset"
e
TEST=lolz ;[ x$TEST = x ] && echo "TEST is unset"

informação relacionada