Escape caracteres do echo -e

1

Eu tenho o seguinte no meu arquivo .bashrc que uso para um log:

function log(){

  RED="\e[0;31m"
  RESET="\e[0m"
  echo -e "${RED}$(date)" "${RESET}$*" >> "$HOME"/mylog.txt
}

Mas quando eu faço algo com um apóstrofo, ele aparece com algum tipo de prompt e não registra corretamente.

Como faço para escapar de todo o texto que está sendo inserido no arquivo?

Exemplo:

$ log this is a testing's post
> hello
> 
> ^C
$

Obrigado.

    
por Proletariat 30.11.2015 / 14:53

2 respostas

7

O problema que você tem não tem nada a ver com echo -e ou sua função log() . O problema é com apóstrofos:

log this is a testing's post

O shell (bash, no seu caso) tem significados especiais para certos personagens. Apóstrofos (aspas simples) são usados para citar sequências inteiras e impedir a maioria dos outros tipos de interpolação. O bash espera que eles venham em pares, e é por isso que você obtém as linhas extras de prompt até que você digite o segundo. Se você quiser uma aspa simples literal em sua string, você precisa dizer bash, por escapar via \' , assim:

log this is a testing\'s post

Novamente, log está além do ponto. Você pode experimentar com o antigo echo , se desejar:

echo this is a testing\'s post

Veja Quais caracteres precisa ser escapado no bash para mais informações.

    
por 30.11.2015 / 16:35
5

Seu problema é porque você digitou uma linha de comando que continha um caractere de aspas simples inigualável. Não tem nada a ver com echo . O shell está emitindo um prompt secundário para informá-lo de que está esperando o final da sequência de aspas simples iniciada por 's po...

Você precisaria escapar do ' se quiser que ele seja passado literalmente à função log :

log "this is a testing's post"

Ou:

log this is a testing\'s post

por exemplo.

Agora, onde você precisa escapar , os caracteres de echo -e são para os caracteres de barra invertida. Por exemplo, se você chamá-lo como log '\begin' , esse \b seria traduzido para um caractere BS por echo -e .

Para resolver isso, armazene as seqüências de escape com aquelas \e expandidas nessas variáveis:

log() {
  RED=$'\e[0;31m'
  RESET=$'\e[0m'
  printf '%s\n' "${RED}$(date) ${RESET}$*" >> "$HOME"/mylog.txt
}

(aqui usando a sintaxe bash , ksh93 , mksh , zsh ou FreeBSD sh para a sintaxe ainda não POSIX $'...' ).

Ou use esta sintaxe:

log() {
  RED='\e[0;31m'
  RESET='\e[0m'
  printf '%b%s%b %s\n' "$RED" "$(date)" "$RESET" "$*" >> "$HOME"/mylog.txt
}

Observe que a expansão de "$*" depende do valor atual de $IFS .

Em qualquer caso, é melhor evitar echo para dados arbitrários .

    
por 30.11.2015 / 16:21