Usando argumentos do comando sed para ser compatível com GNU e BSD Unix (edição no local)

4

Eu tenho um script de shell que uso atualmente para algumas coisas relacionadas à compilação de um aplicativo para dispositivos móveis.

Devido às sutis diferenças entre o BSD & GNU um dos scripts de construção originalmente escritos em um Mac (BSD)

environment=$1

if [[ -z $environment ]]; then 
  environment="beta"
fi
if ! [[ $environment =~ (live|beta) ]]; then
  echo "Invalid environment: $environment"
  exit 1
fi

mobile_app_api_url="https://api"$environment".mysite.com"

cp app/index.html.mob MobileApp/www/index.html

sed -i'' "s#MOBILE_APP_API_URL#\"$mobile_app_api_url\"#g" MobileApp/www/index.html

O comando sed foi escrito no BSD (Mac), mas como os builds podem ocorrer tanto no Mac quanto no Ubuntu (GNU) eu preciso modificar isso para trabalhar com ambos os tipos, qual é a melhor abordagem para isso?

    
por Zabs 03.03.2017 / 15:07

3 respostas

2

Faça isso para contornar os problemas de portabilidade problemáticos com o sinal -i de sed :

sed 'sed-editing-commands' thefile >tmpfile && mv tmpfile thefile

Ou seja, grave em um arquivo temporário e substitua o arquivo de entrada pelo arquivo temporário se o comando sed não falhar.

Isso é portável para todas as implementações de sed que eu conheço.

Para criar um nome de arquivo temporário com segurança, use mktemp . Embora este não seja um utilitário padrão, ele está disponível em todos os Unices aos quais eu tenho acesso (OpenBSD, NetBSD, Solaris, macOS, Linux):

tmpfile=$(mktemp)
sed 'sed-editing-commands' thefile >"$tmpfile" && mv "$tmpfile" thefile
    
por 03.03.2017 / 15:09
0

Você precisa perceber que $mobile_app_api_url não deve conter os caracteres que são significativos para sed no RHS de s ///. Especificamente, falando, você precisa para certificar-se de que esta variável tenha o seguinte corretamente escapado: viz.,      & # \ newline antes de serem conectados.

    
por 03.03.2017 / 15:32
0

Em vez de:

cp app/index.html.mob MobileApp/www/index.html
sed -i'' "s#MOBILE_APP_API_URL#\"$mobile_app_api_url\"#g" MobileApp/www/index.html

Basta fazer:

sed "s#MOBILE_APP_API_URL#\"$mobile_app_api_url\"#g" \
  < app/index.html.mob >  MobileApp/www/index.html

Você também pode remover sua dependência de ksh93 / bash alterando a parte superior para:

environment=$1

case $environment in
  "") environment=beta;;
  live|beta) ;;
  *)
    printf >&2 'Invalid environment: "%s"\n' "$environment"
    exit 1;;
esac

Veja também environment=${1:-beta} .

BTW, [[ $environment =~ (live|beta) ]] em ksh93 e bash testam se $environment contém live ou beta , o que não parece o que você deseja. Você precisaria de [[ $environment =~ ^(live|beta)$ ]] para testar se é live ou beta .

    
por 03.03.2017 / 16:37