Como fazer bash substitution $ (“filename”) silencioso

1

Eu quero substituir o gato:

var=$(cat "filename" 2>/dev/null)

pela sintaxe do bashismo:

var=$(<"filename")

O problema é que eu não sei como tornar o bashismo silencioso para evitar tais avisos:

bash: filename: No such file or directory

Eu tentei isso:

var=$(2>/dev/null <"filename")

mas não lê mais arquivos existentes em var .

    
por rudimeier 06.03.2018 / 13:53

4 respostas

8

Envolvendo a tarefa em um bloco composto e usando um redirecionamento parece funcionar:

{ var=$(<"$file"); } 2>/dev/null;

por exemplo,

$ echo hello > test1; rm -f test2
$ file=test1; { var=$(<"$file"); } 2>/dev/null; echo "${var:-[it is empty]}"
hello
$ file=test2; { var=$(<"$file"); } 2>/dev/null; echo "${var:-"[it is empty]"}"
[it is empty]

Apenas não use ( .. ) para criar um subshell, pois a variável atribuída seria perdida.

    
por 06.03.2018 / 14:27
3

Teste primeiro para se certificar de que está disponível e legível:

if [ -f "filename" ] && [ -r "filename" ]; then
    var=$(<"filename")
fi

O teste -f testa se filename se refere a um arquivo regular e o teste -r testa se é legível por você.

    
por 06.03.2018 / 14:03
1

Outra maneira é primeiro verificar se o arquivo existe e depois lê-lo na variável.

[ -e filename ] && var=$(<filename)
    
por 06.03.2018 / 14:32
1

Para referência:

em zsh , você pode usar a matriz associativa especial $mapfile que mapeia o conteúdo do arquivo nomeado como a chave (observe que ela não é relacionada e é anterior à bash ' mapfile builtin (que não mapeia arquivos) por uma década ou mais). Ele usa mmap() , então só pode ser usado em arquivos regulares.

zmodload zsh/mapfile
var=$mapfile[filename]

Não produz nada se o arquivo não puder ser aberto ou mmapado. Para verificar erros, você pode usar a variável $ERRNO special:

ERRNO=0
var=$mapfile[filename]
if ((ERRNO)); then
  : the mapping failed
fi

$ERRNO valores podem ser convertidos em ENOENT , EACCESS ... códigos com a matriz $errnos no módulo zsh/system ou em sequências de erros com syserror integrado em zsh/system bem.

Você também pode fazer mapfile[filename]=$var para alterar o conteúdo do arquivo, é um verdadeiro mapeamento.

Observe que, embora $(<filename) retire todos os caracteres de nova linha do conteúdo de filename , $mapfile[filename] expande para todo o conteúdo do arquivo (incluindo arquivos binários) como está.

    
por 06.03.2018 / 15:58